ファイナライザーは常に .net フレームワークによって呼び出されるため、シーケンスが制御不能になる可能性があります。コンストラクタが失敗した場合でも、デストラクタをトリガーできます。
このようなファイナライザーの例外がサードパーティのライブラリから発生した場合、これは問題を引き起こす可能性があります: それらを処理する方法が見つかりません!
たとえば、次のコードでは、クラス A のコンストラクターは常に例外をスローして失敗しますが、A のファイナライザーは .net フレームワークによってトリガーされ、A には B 型のプロパティがあるため ~B() も呼び出されます。
class Program // my code
{
static void Main(string[] args)
{
A objA;
try
{
objA = new A();
}
catch (Exception)
{
}
; // when A() throws an exception, objA is null
GC.Collect(); // however, this can force ~A() and ~B() to be called.
Console.ReadLine();
}
}
public class A // 3rd-party code
{
public B objB;
public A()
{
objB = new B(); // this will lead ~B() to be called.
throw new Exception("Exception in A()");
}
~A() // called by .net framework
{
throw new Exception("Exception in ~A()"); // bad coding but I can't modify
}
}
public class B // 3rd-party code
{
public B() { }
~B() // called by .net framework
{
throw new Exception("Exception in ~B()"); // bad coding but I can't modify
}
}
これらが私のコードである場合、少し簡単です-ファイナライザーでtry-catchを使用できます。少なくともログを記録できます-例外がプログラムをクラッシュさせ、エラーをできるだけ早く発見できるようにすることができます-または必要に応じて例外を「許容」し、try-catch を使用して例外を抑制し、正常に終了することができます。
しかし、A と B がサードパーティ ライブラリのクラスである場合、何もできません。発生する例外を制御することはできません。例外をキャッチすることもできないため、ログに記録したり抑制したりすることもできません。
私に何ができる?