【问题标题】:Why does Visual Studio suggest "TODO: set large fields to null."?为什么 Visual Studio 会建议“TODO:将大字段设置为 null。”?
【发布时间】:2020-09-09 03:00:32
【问题描述】:

在 Visual Studio(至少 2010 年)中编写 VB.NET 时,如果您创建一个实现 IDisposable 的类,IDE 将为您生成此框架:

' IDisposable
Protected Overridable Sub Dispose(disposing As Boolean)
    If Not Me.disposedValue Then
        If disposing Then
            ' TODO: dispose managed state (managed objects).
        End If

        ' TODO: free unmanaged resources (unmanaged objects) and override Finalize() below.
        ' TODO: set large fields to null.
    End If
    Me.disposedValue = True
End Sub

如果我正确理解垃圾收集,将字段设置为 null 将毫无用处。* 但是 Visual Studio 为何会推荐它呢?

*假设您没有持有对正在处置的对象的实时引用,这很奇怪。

【问题讨论】:

  • 您不能假设在 Dispose 期间没有人持有对 IDisposable 的实时引用。无论其他对象有什么引用,都可以调用 Dispose。
  • @Jerry 是的,这是可能的,但它(几乎可以肯定)是一个错误,并且可能比没有被 GC 处理的大对象更大。
  • 如果您可以控制相关类的使用,那么您确实应该尝试确保它被正确使用。但是 VS 无法知道您是否正在编写旨在供其他人使用的内容。他们的错误不是您的责任,但您在 Dispose 期间所做的事情

标签: vb.net visual-studio-2010 visual-studio


【解决方案1】:

一般来说,这个自动生成的代码没什么可欣赏的。在过去的 10 年中,一次性模式已经过时,被 .NET 2.0 中的关键终结器优雅地取代。但并没有完全消失,从 1.0 开始的几个 .NET 类实现了它。当你从这样一个类派生时,你就会被覆盖Dispose(Boolean) 方法所困扰。遗憾的是,VB.NET 编辑器不够智能,无法检测到这种极端情况。

对建议进行分类的最佳方法是不要将其标记为正确,而是标记为“没有错误”。只要 VB.NET 程序员盲目地遵循建议,他们就永远不会遇到麻烦。没有错。

“将大字段设置为空”建议也完全属于“正确”类别。它通常不会产生任何影响,但是从技术上讲,“大对象”可能存在于较早的 GC 生成中。这很可能在一次性对象被创建很久之后才被分配。将其设置为Nothing 然后允许GC 更早地释放它并且程序将运行得更精简。没有错。

【讨论】:

  • 如果你的最后一段是真的,那么为什么不在它超出范围之前将任何大对象设置为'null'呢?举个例子,我的意思是,如果您在 sub 中声明并填充了一个非常大的字符串 - 到达 sub 的底部 - 我是否将字符串设置为 null?一般的建议是不要像我想的那样做 - 或者是吗?
  • Hmya,范围与收集对象的确切时间没有太大关系。特别是当范围是 Dispose() 方法时。当您知道对象何时适合收集时总是更好,而当 Dispose() 方法运行后真的很快发生这种情况时总是更好。但是,如果您没有真正的想法,那么您将永远不必感到抱歉。
【解决方案2】:

有人可能会在任意时间内持有对 Disposed 对象的引用。但是作为IDisposable类的实现者,你知道Dispose()之后的大对象是不需要的。要让大对象尽快被收集,请将其设置为 null。

【讨论】:

  • 然而,评论指的是一个“字段”而不是一个对象——这到底是什么意思?我认为您创建了一个需要收集的新空字段,而旧字段只是作为垃圾被收集,就像它一样。
猜你喜欢
  • 1970-01-01
  • 2013-05-10
  • 1970-01-01
  • 2013-05-09
  • 1970-01-01
  • 1970-01-01
  • 2022-11-18
  • 2019-09-12
  • 2011-05-25
相关资源
最近更新 更多