在Dispose()中设置obj = null(Nothing)的意义吗?

ser*_*hio 32 .net c# vb.net dispose memory-management

在方法中将自定义对象设置为null(Nothing在VB.NET中)是否有意义Dispose()?这可以防止内存泄漏或无用吗?!

让我们考虑两个例子:

public class Foo : IDisposable
{
    private Bar bar; // standard custom .NET object

    public Foo(Bar bar) {
        this.bar = bar;
    }
    public void Dispose() {
        bar = null; // any sense?
    }
}

public class Foo : RichTextBox
{
    // this could be also: GDI+, TCP socket, SQl Connection, other "heavy" object
    private Bitmap backImage; 

    public Foo(Bitmap backImage) {
        this.backImage = backImage;
    }

    protected override void Dispose(bool disposing) {
        if (disposing) {
            backImage = null;  // any sense?
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Mar*_*ell 24

我个人倾向于; 有两个原因:

  • 这意味着如果有人忘记释放Foo(可能是从一个事件)任何下游对象(Bitmap在这种情况下)仍然可以收集(在将来的某个时候 - 只要GC感觉像这样); 这可能只是一个围绕非托管资源的浅层包装,但每一点都有帮助.
    • 真的不喜欢因为用户忘记解开一个事件而意外地保持整个对象图形.IDisposable是一个方便的"几乎杀死"开关 - 为什么不分离一切可用?
  • 更重要的是,我现在可以诙谐地使用这个字段来检查(在方法等中)进行处理,ObjectDisposedException如果是的话就扔掉它null

  • @Brian - 注意"意外"和"事件"; 并注意**我不一定是编写*使用*我的组件的代码的人.我无法修复*他们的*代码,但我可以使我的表现良好. (8认同)
  • 对不起,如果出错了.我并不反对这种做法.我只是更喜欢没有这些冗余的稍微简单的代码. (2认同)

Bri*_*sen 20

目的Dispose()是允许清理垃圾收集器未处理的资源.对象由GC处理,因此在正常情况下实际上不需要将引用设置为null.

例外情况是,如果您希望调用者在此之后调用Dispose 保留实例.在这种情况下,将内部引用设置为null是个好主意.然而,一次性实例通常同时被丢弃和释放.在这些情况下,它不会产生很大的不同.

  • 您始终必须决定依赖项的清理位置.如果你知道在其他地方没有使用位图,Foo应该调用`Dispose()`.否则它应该离开它并让调用者处理清理.将本地引用设置为null没有其他好处.当回收Foo的实例时,Bitmap的实例也是如此,除非调用者仍然拥有对它的引用. (4认同)
  • @serhio - 如果你想在Foo中使用它后立即释放你的Bitmap对象使用的资源(没有其他人在使用它),那么Foo.Dispose应该调用backImage.Dispose (2认同)