UPDATE:
I'm sorry but I'm confused. It could be that the confusion comes from old perceptions on GC/Dispose vs. new perception.
If you look here in this (albeit no longer maintained) official Microsoft Documentations, it indicates that Dispose patterns are also used for releasing managed resources:
protected override void Dispose(bool disposing)
{
if (!disposed)
{
if (disposing)
{
// Release **managed** resources. (!!!!!)
}
// Release unmanaged resources.
// Set large fields to null.
// Call Dispose on your base class.
disposed = true;
}
base.Dispose(disposing);
}
This is contrary to what is written in the new version, which states:
Managed memory (memory allocated using the C# operator new) does not need to be explicitly released. It is released automatically by the garbage collector (GC).
Maybe it's just a mistake in the documentation, that threw me off (damn you Microsoft). But maybe - it could be that in the early days of the GC, it was not so trusted, and the guidelines were "you can clean yourself, if you know what you're doing". And now days it's so trusted, that the guidelines are "on managed resources don't ever use, we know better than you". If it's not a mistake - then there's clearly some change or shift in perception here.
As for the question - I won't do anything and will let GC do what it knows best.
Old Question:
I have a TreeView ViewModel class that has nodes in it, which are recursive classes (they can contain themselves).
e.g.
class RootViewModel // root
{
List<ItemViewModel> Children = new List<ItemViewModel>();
}
class ItemViewModel // node
{
List<ItemViewModel> Children = new List<ItemViewModel>();
}
At some point all the data from the TreeView is transferred/saved to other objects, and I don't need the TreeView anymore. I'm guessing I need to dispose of it ? (while the window containing the ViewModel is closed, the ViewModel class object is saved in a static variable).
Do I need to dispose every node by itself (recursive dispose) or is it enough to set the root object to null and call GC ?
I should note that my disposing doesn't have any unmanaged resources, I'm just setting all children in the Children-lists to null for every node.
So again -
You should Dispose
to release unmanaged ressources only, e.g. some file-stream. So when you don´t have any unmanaged resources, no need to use Dispose
at all. See the docs:
Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
Instead just rely on the GC to release all instances as soon as there are no more references to them existing. That is when there´s no variable pointing to it. So in the moment the parent node is released by the GC also its children are (assuming you don´t have any other variables pointing to them). However calling GC.Collect
is almost allways a bad idea, GC is usually doing a good job and you shouldn´t investigate.
Setting your variables to null will however not mark them for garbage-collection unless you have some really big code-block (e.g. one single method containing thousands of lines). In this case your variables may not get out of scope for a long time. Doing this is therefor more a sign of a code-smell, you should devide your code into smaller parts that do one single thing.