質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Q&A

解決済

1回答

7841閲覧

親クラスと子クラスで共通のインスタンスを参照したい場合のベストプラクティスについて

退会済みユーザー

退会済みユーザー

総合スコア0

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

0グッド

0クリップ

投稿2017/01/22 07:56

編集2017/01/22 07:59

お世話になっております。

実装でちょっと困ったことがあり相談に乗っていただければと思います。

以下は現在書いているプログラムのダミーになりますが、今までstatic classで以下のように共通の変数を持たせていました。
(アクセサなどは適当です。動作確認していませんのであくまで例示コードだと思って補間していただけると助かります)

C#

1 2//Params.cs 3static class Params{ 4 public int a{get;set;}=0; 5 public double b{get;set;}=0; 6 7} 8 9//A.cs 親クラス 10using static Params; 11class A { 12 B b; 13 double aValue{get;set;} 14 15 double someCalc{ 16 return a+aValue; 17 } 18 19} 20 21//B.cs 子クラス 22using static Params; 23class B { 24 25 double bValue{get;set;} 26 27 double someCalc{ 28 b = someOtherRewriteFunction(); //bの値を書き換えるメソッド 29 return a+b+bValue; 30 } 31} 32 33

しかし、この値は、serializeして保存することと最終的にAクラスのインスタンスごとに異なった値をとれた方が可用性がいいことに気づき、親クラスと子クラスから同じインスタンスを参照するように変更しようと思った所,staticでないクラスで書き直したところ以下のようになりました。

C#

1 2//Params.cs 3[serializable] 4class Params{ 5 public int a{get;set;}=0; 6 public double b{get;set;}=0; 7} 8 9//A.cs 10class A { 11 Params params {get;set;} 12 B b; 13 14 public A(){ 15 this.params = new Params(); 16 this.b = new B(params); 17 } 18 19 double aValue{get;set;} 20 21 double someCalc{ 22 return params.a+aValue; 23 } 24 25} 26 27//B.cs 28class B { 29 Params params {get;set;} 30 public B(Params params){ 31 this.params = params; 32 } 33 double bValue{get;set;} 34 35 double someCalc{ 36 params.b = someOtherRewriteFunction(); //bの値を書き換えるメソッド 37 return params.a+params.b+bValue; 38 } 39} 40 41

実際はParamsクラスの値を使用するメソッドが大量にあるので、引数を増やさないようにしたかったのでこうなりました(そもそも値もその時点で持っているものを計算で更新するので結局参照でもつ必要があるので引数不要だと思いました。)。この実装で問題点とかないでしょうか?もし他によりよい修正方法があれば教えていただきたいです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

親のポインタを持つ子クラスを作ることは度々ありますから、問題ないんではないでしょうかね。
※シリアライズするって要件が発生するとデフォルトでサポートされていないので色々悩まされますが。笑

しいて言えばそのデザインだとParam`をデシリアライズする際、AとB両方に再設定が必要ってことぐらいでしょうか。親子関係が明確であればネストしてしまっていいと思うんですが、先ほどいったようにネストするのはシリアライズ/デシリアライズを工夫する必要があって面倒です。

下記の形でparamsは後で代入っていうなら問題ないですけどね。

C#

1class A { 2 private readonly B b; 3 Params params { get; set; } 4 5 public A(){ 6 this.params = new Params(); 7 this.b = new B(this); 8 } 9 10 class B { 11 private readonly A parent; 12 public B(A parent){ 13 this.parent = parent; 14 } 15 double accessingToParentParam() { 16 return parent.params.a + parent.params.b; 17 } 18 } 19}

投稿2017/01/23 01:56

haru666

総合スコア1591

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2017/01/23 02:07 編集

確かに再代入の可用性考えるとインナークラス毎シリアライズした方が楽ですね。親のモデルの参照毎子に渡してしまうというやり方はrubyではよくやるのにC#だと盲点でした。 この実装いいですね。ありがとうございます!
haru666

2017/01/23 02:14

java等でサポートされている親ポインタの参照っていうのがC#には無いので、このデザインで子クラス毎シリアライズするのは意外と面倒…だった気がします。たぶん。今なら良い解決策が出てるかもしれませんが。
退会済みユーザー

退会済みユーザー

2017/01/23 07:36

なるほど。試したことないので、検証してみますね。 最悪Paramsだけシリアライズして引数で引きずり回せばいいので抱えていた問題は解決しそうです。 ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問