I started creating a small testprogram to prove that the scope of abcTest
is different from the
lifetime of abcTest
. While doing that I bumped into a problem that the Finalizer of ABC
is called only after the main function completes. I thought it would get called on GC.Collect() since I set the object to null abc = null;
in BCD
s destructor. Please see the below code
namespace ConsoleApp1
{
public class ABC
{
public void SaveReferenceToBCD(BCD bcdObj)
{
bcdObj.SetABCObject(this);
}
public void SayHello()
{
Console.WriteLine("\tHello from ABC");
}
~ABC()
{
Console.WriteLine("\tDestructor of ABC");
}
}
public class BCD
{
ABC abc = null;
public void SetABCObject(ABC value)
{
abc = value;
}
public void SayHello()
{
abc.SayHello();
Console.WriteLine("\tHello from BCD");
}
~BCD()
{
abc = null;
Console.WriteLine("\tDestructor of BCD");
}
}
public class Workout
{
static void Main()
{
{
BCD bcdTest = new BCD();
{
ABC abcTest = new ABC();
abcTest.SaveReferenceToBCD(bcdTest);
// abcTest = null;
/* If I uncomment the above line I get Output 2,
* but I thought Output 1 should be same as Output 2, given that I set
* the value of "abc" to null in "BCD"s destructor */
}
Console.WriteLine("First GC Collect Start");
GC.Collect();
GC.WaitForPendingFinalizers();
Console.WriteLine("First GC Collect END");
bcdTest.SayHello();
bcdTest = null;
}
Console.WriteLine("Second GC Collect Start");
GC.Collect();
GC.WaitForPendingFinalizers();
Console.WriteLine("Second GC Collect END");
Console.WriteLine("Third GC Collect Start");
GC.Collect();
GC.WaitForPendingFinalizers();
Console.WriteLine("Third GC Collect END");
}
}
}
Output 1 Received: (with abcTest = null
commented out)
First GC Collect Start
First GC Collect END
Hello from ABC
Hello from BCD
Second GC Collect Start
Destructor of BCD
Second GC Collect END
Third GC Collect Start
Third GC Collect END
Destructor of ABC (Printed only after the main function finishes its execution)
Output 2 Received: (with abcTest = null
NOT commented out)
First GC Collect Start
First GC Collect END
Hello from ABC
Hello from BCD
Second GC Collect Start
Destructor of ABC
Destructor of BCD
Second GC Collect END
Third GC Collect Start
Third GC Collect END
I expected the Output 1 to have Destructor of ABC
as well (similar to Output 2), given that I set
the value of "abc" to null in "BCD"s destructor itself. Please help. Thanks!