user3002473
user3002473

Reputation: 5074

C# - Disposing Recursive Objects

Lets say I have some object C that holds references to instances of itself, and also implements IDisposable. How should the references to other instances of C be disposed of? Should I recursively call their dispose methods or should I just set them equal to null? In other words, which of the following models is preferred?

Model 1: Recursive Disposing

public class C : IDisposable
{
    public List<C> subItems = new List<C>();

    public void Dispose() 
    {
        foreach (C subItem in subItems)
            subItem.Dispose();
        // Dispose other stuff
    }
}

Model 2: Disposing by setting equal to null

public class C : IDisposable
{
    public List<C> subItems = new List<C>();

    public void Dispose() 
    {
        subItems = null;

        // Dispose other stuff
    }
}

Upvotes: 2

Views: 1202

Answers (3)

Henk Holterman
Henk Holterman

Reputation: 273449

Should I recursively call their dispose methods

Yes.

But only when C actually needs to be IDisposable, which is not obvious from your code. The fact that it is referring to instances of the same class is not relevant, call Dispose() on all owned IDisposable objects.

If this is an attempt to 'help' the Garbage collector, then stop it and just do nothing.

Upvotes: 8

comdiv
comdiv

Reputation: 951

It's not only right answer.

The main question you have to ASK - is conainer of LIST real and single OWNER of items in it?

If so - the only valid behavior - call Dispose explicitly (as in your first pseudo-code)

If items are or could be shared and can be used in another contexts rather than single container (for example as it is with StreamWriter and Stream - StreamWriter can be "owner" of Stream and close it, but you can use keepLive parameter to keep Stream opened). In shared case the only valid way would be run from such situations - because if you dispose - you could break other tasks, if not dispose and just clear list - you can keep some of resources alive without any chance to clean.

Where are ninja way for shared as it maked in shared_ptr in C++ or usual references in .NET - trace usage count -

class C:IDisposable{
    int usageCount = 0;
    public void AddUsage(){usageCount++;}; 
    public void Dispose(){
         if(usageCount>0){
            usageCount--;
            return;
         }
         //ELSE DO REAL DISPOSE LOGIC
    }
 }

BUT wish it's not your case )

Upvotes: -1

Nick Rimmer
Nick Rimmer

Reputation: 11

Should I recursively call their dispose methods

No. if you no need it. (GC cleaned it)

Yes. if object uses unmanaged resources. Not disposing unmanaged resources will lead to memory leaks.

Upvotes: -1

Related Questions