クラスAのプロパティの1つとしてクラスBがあり、クラスBのプロパティの1つとしてクラスAがあるような循環参照問題をどのように解決しますか?
これらの種類の問題をどのように設計するのですか?
NHibernateを例にとると、オブジェクト間に親子関係があります。
どのようにしてそれらの親子シナリオを処理できますか?
2つのものを相互に参照させる必要があったほとんどの場合、循環参照を削除するためのインターフェースを作成しました。例えば:
[〜#〜]前[〜#〜]
public class Foo
{
Bar myBar;
}
public class Bar
{
Foo myFoo;
}
依存関係グラフ:
Foo Bar
^ ^
| |
Bar Foo
FooはBarに依存していますが、BarもFooに依存しています。それらが別のアセンブリにある場合、特にクリーンな再構築を行う場合、構築に問題があります。
[〜#〜]後[〜#〜]
public interface IBar
{
}
public class Foo
{
IBar myBar;
}
public class Bar : IBar
{
Foo myFoo;
}
依存関係グラフ:
Foo, IBar IBar
^ ^
| |
Bar Foo
FooとBarはどちらもIBarに依存しています。循環依存はなく、IBarが独自のアセンブリに配置されている場合、FooとBarが別々のアセンブリにあることは問題ではなくなります。
私はあなたの友人に彼が彼のデザインを再考する必要があると言います。あなたが説明するような循環参照は、しばしば設計上の欠陥のコード臭いです。
C++(たとえば)とは異なり、C#は循環参照を解決するために前方宣言を必要としません。したがって:
public class A
{
public B B { get;set; }
}
public class B
{
public A A { get;set; }
}
ただし、これは多くの場合、疑わしい設計決定の指標です。
ほとんどの場合、最善の解決策は、設計を変更して循環依存を回避することです。たとえば、次のいずれかを実行できます。
ただし、多くのプロジェクトを含むソリューションで作業していて、コードを所有していないために上記の変更のいずれかを行うことができない場合は、実装するのが困難であるか、修正する価値がありません。次に、このメソッドを使用できます:
プロジェクト参照を右クリックし、[参照の追加...]を選択します。次に、表示されるダイアログウィンドウで、[参照]タブと[参照]ボタンに切り替えます。そこからDLL=を見つけて選択します。これはせいぜい回避策であり、特に両方のDLLが頻繁に更新されている場合や、多くの依存関係がある場合に、ビルドの問題を引き起こす可能性があります。この方法はお勧めしませんが、ピンチで機能します。
フィッシュ
ただし、多くのことのアーキテクチャをやり直すよりも迅速な解決策を探している場合は、すべてのデータ構造を保持する1つのDLLクラスライブラリを構築してみてください。メインプロジェクトは、そのデータを必要とするUIを保持し、次に、必要な他のDLLを保持します。追加することで、データ構造dllにもアクセスできるため、実行に必要なすべての情報を取得できますが、分離することもできます。これは、トライフォース設計パターンと呼ばれます。
循環参照は、2つ以上の相互依存するリソースがロック状態を引き起こしたときに発生します。これにより、リソースが使用できなくなります。
C#で循環参照の問題を処理するには、ガベージコレクションを使用する必要があります。循環参照を検出して収集します。ガベージコレクターは、ローカルおよび静的で始まり、子を介して到達できる各オブジェクトをマークします。
これにより、循環参照の問題を処理できます。
次のクラスが循環参照しているとしましょう。ここでそれらの両方は互いに依存しています-
public class A
{
B Two;
}
public class B
{
A one;
}
問題を解決するには、インターフェイスを作成します-
public interface myInterface {
}
public class A {
myInterface Two;
}
public class B: myInterface {
A one;
}