2010-11-23 6 views
0

大量のコードを読み込むことは残念です。それは問題を示す最も簡単な方法です。サブクラスのコンストラクタ例外は親クラスのインスタンスを残します

using System; 
using System.Collections.Generic; 

namespace P1 
{ 
    class A 
    { 
     static Dictionary<int, A> a = new Dictionary<int, A>(); 
     static int i = 0; 

     int id; 
     public A() 
     { 
      id = ++i; 
      a[id] = this; 
     } 

     public static int Count() { return a.Count; } 
    } 

    class B : A 
    { 
     public B() 
     { 
      throw new Exception(); 
     } 
    } 

    class Program 
    { 
     static void Main(string[] args) 
     { 
      try 
      { 
       var b = new B(); 
      } 
      catch 
      { 
       // What should be here ???? 
      } 

      Console.WriteLine(A.Count()); //prints 1 - not good 
      Console.ReadKey(); 
     } 
    } 
} 

誰でもサブクラスのコンストラクタが失敗した場合のクリーンアップロジックを提案できますか?

+0

'B'のコンストラクタが失敗した場合、あなたのプログラムは何とか​​回復できますか?なぜ「1」は「良くないのですか」? –

+0

bが失敗しても、aのインスタンスは残っており、削除方法はわかりません。 – Marko

+0

@Marko:オブジェクト作成の懸念と辞書へのオブジェクトの挿入の懸念を区別すると、この質問は発生しません。 –

答えて

1

コンストラクターが失敗した後でインスタンス参照にアクセスできないため、クリーンアップロジックをBのコンストラクターに配置する必要があります。ここで

は、あなたがこれを行うことができます方法の例です:例外がスローされる前に

class A 
{ 
    static Dictionary<int, A> a = new Dictionary<int, A>(); 
    static int i = 0; 

    int id; 
    public A() 
    { 
     id = ++i; 
     a[id] = this; 
    } 

    protected void Destroy() 
    { 
     a.Remove(id); 
     i--; 
    } 

    public static int Count() { return a.Count; } 
} 

class B : A 
{ 
    public B() 
    { 
     try 
     { 
      throw new Exception(); 
     } 
     catch (Exception) 
     { 
      Destroy(); 
      throw; 
     } 
    } 
} 
+0

どうすればいいですか? – Marko

+0

'x = new B();と言うなら、これはうまくいかないことに注意してください。 y =新しいB(); x = null; GC.Collect(); x = new B(); 'これを行うと、ID 2の2つのAがあり、そのうちの1つだけが辞書に入ります。これは、サブクラスオブジェクトの作成が成功したと仮定しています。 – Kendrick

+0

面白い...面白いですが、サブクラスタイプがたくさんあるので、私には十分ではありません。( – Marko

0

あなたの基底クラスのコンストラクタが呼び出されているので、オブジェクトがすでにaで作成され、それのスポットに割り当てられています。コンストラクタによってオブジェクトが作成されないようにするには、デフォルトのコンストラクタを使用する代わりに、新しいAをインスタンス化する静的メソッドを検討するとよいでしょう。オブジェクトのインスタンス化が失敗すると(Bで)、オブジェクトが辞書に追加される前に例外がスローされます。