Search code examples
c#genericsgarbage-collectiondisposeidisposable

How do I mark the generic "T Value" as ready for disposal?


I've created a class BinaryTree<T>. I wrote the following to dispose it:

public override void Dispose()
{
    this.Key = null;
    //delete this.Value;
    if(this.LeftLeaf != null) this.LeftLeaf.Dispose();
    this.LeftLeaf = null;
    if(this.RightLeaf != null) this.RightLeaf.Dispose();
    this.RightLeaf = null;
    base.Dispose();
}

My question is how do I mark the "T Value" as ready for disposal? I can't set it to null because you can't set generics to null. T could be a giangantic class, but it may not be using IDisposable so you can't call Dispose on it. Since this is "safe" class written like an "unsafe" class I don't trust GC to figure out it's not being used anymore.


Solution

  • If for some reason you're writing a generic collection in which you know that the elements of your collection will implement IDisposable and the collection will be responsible for disposing of them (which, generally is something you would not expect of the collection) then you should be adding the generic constraint where T : IDisposable so that you can dispose of all of the items.

    When it comes to normal collection of managed types, as opposed to unmanaged resources, you don't need to do anything. There's no need to set the fields to null, or the value to null. If the entire collection isn't referenced anywhere then the GC will collect it, and any values not referenced anywhere, even without you nulling out all fields.

    I don't trust GC to figure out it's not being used anymore

    That's going to make C# pretty much unusable for you as a language. By design, not only do you not have to manually release managed resources, you can't even if you wanted to. There is no way for you to force a managed object to be cleaned up immediately. You can only manually clean up unmanaged resources. If, for some reason, this is unacceptable for your application and you must have complete control over the memory management of your program you'll want to use some other language with more explicit memory management (or perhaps write some particularly sensitive parts in another language, and interop with C# for the rest).