I was recently going through a garbage collection article and decided to play along and attempt to gain a greater understanding. I coded the following, playing around with the using statement, but was surprised with the results… I expected e.Parent.Name outside of the using block to go ka-blooey.
What exactly is going on here?
static void Main(string[] args)
{
Employee e = new Employee();
using (Parent p = new Parent())
{
p.Name = "Betsy";
e.Parent = p;
Console.WriteLine(e.Parent.Name);
}
Console.WriteLine(e.Parent.Name);
Console.ReadLine();
}
public class Employee
{
public Parent Parent;
}
public class Parent : IDisposable
{
public string Name;
public void Dispose()
{
Console.WriteLine("Disposing Parent");
}
}
Your Dispose method doesn’t actually do anything to the instance of
Parent, hence it’s still fair game / works as a usable instance of a class.IDisposableis usually used when your class holds onto an unmanaged resource, such as a database connection or a file, so that it can be cleaned up whenDispose()is called. Just callingDisposedoesn’t do anything to the unmanaged resources, there has to be some code in the method that does something to those resources. Whilst c# might have theusing() {}syntax to wrap instantiation and disposal of anIDisposableobject in a try/catch/finally, it doesn’t mean it does anything "special" with the disposed object.Imagine, hypothetically, that
Nameis actually an unmanaged resource, rather than just a string, yourDispose()method could read:Because you’ve assigned
ptoe.Parent, the object itself is still "in scope" as there’s a reference to it, hence it’s still accessible forConsole.WriteLine(e.Parent.Name);to produce output from.It’s also currently "CLR Week" over at The Old New Thing and the first 3 articles of the week are discussing the Garbage Collector and how it works/behaves. They’re well worth a read: