C# 在C中处理递归类#

C# 在C中处理递归类#,c#,mvvm,dispose,C#,Mvvm,Dispose,更新: 对不起,我很困惑。这可能是由于对GC/Dispose的旧看法与新看法不同而造成的混淆 如果您在这里查看(尽管不再维护)官方,它表明Dispose模式也用于释放托管资源: protected override void Dispose(bool disposing) { if (!disposed) { if (disposing) { // Release **managed** resources. (!!!!!)

更新:

对不起,我很困惑。这可能是由于对GC/Dispose的旧看法与新看法不同而造成的混淆

如果您在这里查看(尽管不再维护)官方,它表明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);
}
这与合同中的规定相反,合同中规定:

托管内存(使用C#运算符new分配的内存)不可用 需要明确发布。它由系统自动释放 垃圾收集器(GC)

也许这只是文档中的一个错误,这让我很生气(该死的微软)。但也许-可能是在GC的早期,它不那么受信任,指导方针是“如果你知道自己在做什么,你可以自己清洗”。现在,它是如此值得信赖,以至于指导方针是“关于管理资源,我们永远不会使用,我们比你更清楚”。如果不是错误的话- 很明显,这里的观念发生了一些变化

至于这个问题,我不会做任何事情,我会让GC做它最了解的事情


老问题:

我有一个TreeView ViewModel类,其中包含节点,这些节点是递归类(它们可以包含自己)

e、 g

class RootViewModel//root
{
列表子项=新列表();
}
类ItemViewModel//node
{
列表子项=新列表();
}
在某个时刻,来自TreeView的所有数据都被传输/保存到其他对象,我不再需要TreeView了。我想我需要把它处理掉?(当包含ViewModel的窗口关闭时,ViewModel类对象保存在静态变量中)

我是否需要单独处理每个节点(递归处理),或者将根对象设置为null并调用GC就足够了

我应该注意,我的服务器没有任何非托管资源,我只是将每个节点的子列表中的所有子节点都设置为null

所以再次-

  • 选项A:将静态对象设置为null,调用GC.Collect()
  • 选项B:递归地将所有节点设置为null,将静态对象设置为null, 调用GC.Collect()从目前为止的回答和评论来看,这似乎是不可能的
  • 选项C:GC看到您停止使用静态对象,所以它将自己处理它

  • 您应该
    Dispose
    仅释放非托管资源,例如某些文件流。因此,当您没有任何非托管资源时,根本不需要使用
    Dispose
    。见:

    执行与释放、释放、, 或者重置非托管资源

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


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

    @davidefaeli如果是静态变量,你可以将其设置为null,或者在应用程序终止时依靠GC释放它。一旦不再存在对实例的引用,依靠GC释放所有实例。我知道,这是因为没有变量指向它挑剔,但与手头的问题有点相关。规则是不可到达的引用;如果对象的引用指向该对象,则可以收集这些对象(如果它们不可访问)。这使反GC能够收集相互引用但无法访问的对象。只是有点吹毛求疵,但FileStream是一种托管资源。应用程序程序员几乎不必处理非托管资源。@HenkHolterman:
    FileStream
    实现了
    IDisposable
    。因此,任何使用
    FileStream
    作为实例属性的类(而不是使用
    块包装在
    中的本地类)仍然应该实现
    IDisposable
    (但不需要实现终结器)。是、是和是。不太清楚你为什么认为需要告诉我。如果你的解决方案包括强制垃圾收集的要求,那么你做的事情非常非常错误。此外,你似乎对一次性物品和垃圾收集之间的关系有一些错误的看法;记住,处置就是释放未被垃圾收集的资源。你没有一个选择是正确的。你实际上有什么问题要解决?然后你需要做一些以用户为中心的测量。你的用户有什么问题?一旦你可以测量这个问题,你就可以做实验,发现你的改变是在经验上改善还是在降低用户体验。我注意到,导致垃圾收集通常会降低用户体验,因为它们会使应用程序无响应。如果您没有影响用户的问题,那么请将宝贵的时间花在其他事情上,而不是“修复”任何人都没有的问题。将您的模型存储在静态变量中似乎不是一个好主意,它会导致您试图解决的问题。是否可以避免将其存储在静态变量中?例如,将其存储在您的ViewForm中,这样当表单关闭时,GC将收集模型。另请参见Brian在我的回答下的评论。
    class RootViewModel // root
    {
       List<ItemViewModel> Children = new List<ItemViewModel>();
    }
    
    class ItemViewModel // node
    {
        List<ItemViewModel> Children = new List<ItemViewModel>();
    }