2

私はC#アプリケーションを開発しており、EmployeeクラスとOrganizationクラスがあります。

Employeeオブジェクトには、内部メンバーとして組織があり、Organizationオブジェクトには、組織リーダーを示すEmployeeメンバーがあります。

この設定には、無限の循環インスタンス化につながる可能性のある問題がありますか?

編集:

コードを実行してみましたが、問題があるようです。従業員オブジェクトはOrganizationオブジェクトをインスタンス化し、Organizationオブジェクトはemployeeオブジェクトをインスタンス化しようとします。どちらもデータベースに接続して詳細を入力します

これは、SQLサーバーの接続がなくなるまで発生し続けます。私がしていることに代わるものはありますか?

4

3 に答える 3

4

いいえ。正常にコンパイルされます。C#コンパイラは、「まだコンパイルされていない」場合でも、すべての型を考慮に入れるのに十分なほど賢いです。Javaと同様に、定義/宣言も同じです(これは、たとえばC / C ++とは異なります)。

于 2010-10-17T21:54:28.467 に答える
2

この設定には、無限の循環インスタンス化につながる可能性のある問題がありますか?

参照型は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;
  }
}

依存性注入はこの問題を解決するために考案されたものではありませんが、このシナリオでは機能することに注意してください。これを使用すると、この問題が二度と発生しないことを知って、安心して休むことができます。

于 2010-10-17T22:04:21.823 に答える
1

発生している問題はC#自体ではない可能性がありますが、おそらくコードが無限ループに入り、組織が従業員に情報を要求しているため、従業員は組織に同じ情報を再度要求します...

このリンクを解除するだけで、組織に関する情報を要求しても、その従業員への呼び出しが連鎖することはありません(その逆も同様です)。つまり、組織の完全な情報が必要な場合は、

org.GetAbsolutelyAllInformation();

あなたは電話します

org.GetOrganisationInformation();
org.Leader.GetEmployeeInformation();

情報をまとめて返す必要がある場合は、新しいオブジェクトで情報を返すのではなく、入力する「空白」のオブジェクトを渡します。すでに入力されているオブジェクトで呼び出された場合は、キャッシュされた情報を返します。データベースから再度フェッチするのではなく。そうすれば、メソッドが呼び出される順序は関係ありません。メソッドは、渡したオブジェクトに組織またはリーダーの情報を入力するだけで、次の反復ですべてのメソッドが検出されたときに「ループ」が停止します。情報が入力されています。

一般に、この種のループが最初に発生するリスクを減らす1つの方法は、組織の「リーダー」を直接参照ではなくID(従業員番号など)にすることです。これにより、このコードを使用するプログラマーは、リーダーIDを取得し、別のステップとしてリーダーの情報を検索するようになります。

于 2010-10-17T22:32:51.677 に答える