在C#中配置递归类

时间:2017-09-03 14:34:05

标签: c# mvvm dispose

更新:

我很抱歉,但我很困惑。可能是混淆来自对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为每个节点。

再次 -

  1. 选项A:将静态对象设置为null,调用GC.Collect()。
  2. 选项B:递归地将所有节点设置为null,将静态对象设置为null, 调用GC.Collect()。 - 到目前为止根据答案和评论似乎是不可能的
  3. 选项C:GC看到您停止使用静态对象,因此它将自行处理它。

1 个答案:

答案 0 :(得分:1)

您应Dispose仅发布非托管资源,例如一些文件流。因此,当您没有任何非托管资源时,根本不需要使用Dispose。见the docs

  

执行与释放,释放相关的应用程序定义的任务,   或重置非托管资源。

相反,只要不再存在对它们的引用,就依赖GC来释放所有实例。那是没有变量指向它的时候。因此,当GC释放父节点时,其子节点也是(假设您没有任何其他变量指向它们)。但是,调用GC.Collect几乎总是一个坏主意,GC通常做得很好,你不应该调查。

将变量设置为null将将它们标记为垃圾收集,除非您有一些非常大的代码块(例如,一个包含数千行的单个方法)。在这种情况下,您的变量可能不会长时间超出范围。这样做更多的是代码嗅觉的标志,你应该将你的代码分成更小的部分来完成一件事。