Reputation: 5074
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
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
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
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