Finalizers are always called by .net framework, so the sequence could be out of control; and even if the constructor failed, the destructor still can be triggered.
This could bring troubles, when such finalizer exceptions come from a 3rd-party library: I can't find a way to handle them!
For example, in the code below, although class A's constructor always throw an exception and fail, finalizer of A will be triggered by the .net framework, also ~B() is called as A has a property of B type.
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
}
}
If these are my code, it is a bit easier - I can use try-catch in finalizers, at least I can do some logging - I can allow the exception to crash the program, to discover the error asap - or if I want to "tolerate" the exception, I can have a try-catch to suppress the exception, and have a graceful exit.
But if A and B are classes from a 3rd-party library, I can do nothing! I can't control the exception to happen, I can't catch them, so I can't log it or suppress it!
What can I do?
A
andB
). – Redden