更新:
我很抱歉,但我很困惑。可能是混淆来自对GC / Dispose与新感知的旧观念。
如果您在此处查看(虽然已不再维护)官方 Microsoft Documentations,则表示Dispose模式也用于释放托管资源:
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);
}
这与new version中的内容相反,后者指出:
托管内存(使用C#operator new分配的内存)不会 需要明确发布。它由。自动释放 垃圾收集器(GC)。
也许这只是文档中的一个错误,让我失望(该死的微软)。但也许 - 可能是在GC的早期阶段,它并不那么受信任,而且指导方针是“如果你知道自己在做什么,你可以自己清理”。现在几天它是如此受信任,指导方针是“在托管资源上永远不会使用,我们比你更了解”。如果这不是一个错误 - 那么这里的感知显然会发生一些变化或转变。
关于这个问题 - 我不会做任何事情,让GC做他们最了解的事情。
旧问题:
我有一个TreeView ViewModel类,其中包含节点,它们是递归类(它们可以包含它们自己)。
e.g。
class RootViewModel // root
{
List<ItemViewModel> Children = new List<ItemViewModel>();
}
class ItemViewModel // node
{
List<ItemViewModel> Children = new List<ItemViewModel>();
}
在某些时候,来自TreeView的所有数据都被传输/保存到其他对象,我不再需要TreeView了。我猜我需要处理它吗? (当关闭包含ViewModel的窗口时,ViewModel类对象将保存在静态变量中。)
我是否需要自己处理每个节点(递归处理)或者是否足以将根对象设置为null并调用GC?
我应该注意,我的处理没有任何非托管资源,我只是将Children-lists中的所有子项设置为null为每个节点。
再次 -
答案 0 :(得分:1)
您应Dispose
仅发布非托管资源,例如一些文件流。因此,当您没有任何非托管资源时,根本不需要使用Dispose
。见the docs:
执行与释放,释放相关的应用程序定义的任务, 或重置非托管资源。
相反,只要不再存在对它们的引用,就依赖GC来释放所有实例。那是没有变量指向它的时候。因此,当GC释放父节点时,其子节点也是(假设您没有任何其他变量指向它们)。但是,调用GC.Collect
几乎总是一个坏主意,GC通常做得很好,你不应该调查。
将变量设置为null将不将它们标记为垃圾收集,除非您有一些非常大的代码块(例如,一个包含数千行的单个方法)。在这种情况下,您的变量可能不会长时间超出范围。这样做更多的是代码嗅觉的标志,你应该将你的代码分成更小的部分来完成一件事。