この設定には、無限の循環インスタンス化につながる可能性のある問題がありますか?
参照型はnull
デフォルトです。新しいインスタンスをインスタンス化してその変数に割り当てない限り、そのタイプのコードは呼び出されません。
各コンストラクターは他のオブジェクトのインスタンスを構築しますか?彼らが将来(おそらく事故で)できる可能性はありますか?もしそうなら、はい、あなたはあなたが話しているシナリオを打つことができます:
class A
{
public A()
{
this.B = new B();
}
public B B;
}
class B
{
public A A = new A(); // This is the same as instantiating the object in the ctor
}
// ...
A obj = new A(); // This calls new B, which calls new A, repeat ad infinitum
コンストラクターの外部で他のオブジェクトのインスタンスをインスタンス化することにより、このようなサイクルを中断できます。たとえば、最初のアクセス時:
class A
{
public A()
{
}
public B B
{
get
{
if(b == null)
b = new B();
return b;
}
}
private B b;
}
class B
{
public B()
{
}
public A A
{
get
{
if(a == null)
a = new A();
return a;
}
}
private A a;
}
// ...
A obj = new A(); // new B doesn't get called yet
obj.B.Something(); // ... Now it does...
class A
コンストラクター内の独自のプロパティにアクセスしないように注意する必要がありますthis.B
。その逆も同様です。ただし、これらのメソッドがコンストラクター内で呼び出されない限り、必要なすべてのメソッドでこれらのプロパティにアクセスできます。
別のオプションは、依存性注入を行うことです。これは、オブジェクト自体をインスタンス化させるのではなく、オブジェクトに依存関係を渡す場所です。
class A
{
public A(B b)
{
this.B = b;
}
public B B;
}
class B
{
public B(A a)
{
this.A = a;
}
public A A;
}
// ...
A someA = new A(
new B(
null)); // You have to break the cycle somewhere...
someA.B.A = someA;
// or ...
class ABFactory
{
public static A CreateA(/* options for a */, /* options for b */)
{
A result = new A(
new B(
null));
result.B.A = result;
return result;
}
}
依存性注入はこの問題を解決するために考案されたものではありませんが、このシナリオでは機能することに注意してください。これを使用すると、この問題が二度と発生しないことを知って、安心して休むことができます。