首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >与IDisposable混淆

与IDisposable混淆
EN

Stack Overflow用户
提问于 2012-11-26 19:35:29
回答 2查看 230关注 0票数 3

对于实现IDisposable的正确方式,我有一些挥之不去的疑问。考虑下面的场景...

代码语言:javascript
复制
public class Foo : IDisposable {...}

public class Bar : IDisposable {

    private bool disposed = false;
    private readonly Foo MyFoo;

    public Bar() {
        this.MyFoo = new Foo();
    }
    public Bar(Foo foo) {
        this.MyFoo = foo;
    }
    ~Bar() {
        Dispose(false);
    }

    protected virtual void Dispose(bool disposing) {
        if (!this.disposed) {
            if (disposing) {
               if (MyFoo != null) {
                   this.MyFoo.Dispose();
                   this.MyFoo = null;
               }
            }
            this.disposed = true;
        }
    }

    public void Dispose() {
        Dispose(true);
        GC.SuppressFinalize(this);
    }
}

我的问题是:

1)如果一个类创建了一个disposable对象,它是否应该在自己的Dispose()方法中调用该对象的Dispose()方法?

2)如果可处置对象作为引用传递给类,该类是否仍应对该引用对象调用Dispose()方法,还是应将其留给最初创建该对象的类?

上面的模式似乎经常出现(特别是在DI中),但我似乎找不到正确的构建方式的具体示例。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-11-26 20:15:01

代码语言:javascript
复制
~Bar() {
    Dispose(false);
}

每当你发现自己在写这样的代码时,先深呼吸一下,问一问“我真的需要终结器吗?”(do actually need a finalizer)?极少需要终结器,只有当您自己获得非托管资源的所有权时,才需要终结器。

第一个试金石测试是“do The finalizer actually do?”如果你遵循代码,那就很清楚了。它调用Dispose(false),只有当参数为true时,代码才会执行某些操作。接下来的事情就是你不需要aa finalizer。这是完全正常的,终结器是微软担心的东西。他们编写了包装非托管资源的.NET框架类。FileStream,Socket,等等。最重要的是SafeHandle类,旨在包装操作系统句柄。他们有自己的终结器,你不需要自己重写。

因此,如果没有终结器,代码将完全折叠为简单而正确的实现,您只需调用您自己存储的任何可处理对象的Dispose()方法:

代码语言:javascript
复制
public class Bar : IDisposable {
    private readonly Foo MyFoo;
    public Bar() {
        this.MyFoo = new Foo();
    }
    public void Dispose() {
        MyFoo.Dispose();
    }
}
票数 1
EN

Stack Overflow用户

发布于 2012-11-26 19:41:15

请参阅优秀的MSDN文章 Garbage Collection: Automatic Memory Management in the Microsoft .NET Framework

1)如果一个类创建了一个Dispose对象,它是否应该在自己的Dispose()方法中调用该对象的Dispose()方法?

是的,应该是这样。否则,还将调用Dispose。但这将使物体的寿命至少增加1代。这是由于类定义中的终结器造成的。请参阅上面的文章链接。

2)如果一个可处置的对象作为引用传递给一个类,那么该类应该仍然对该引用对象调用Dispose()方法,还是应该把它留给最初创建该对象的类?

调用Dispose方法是调用者(更具体地说是创建了一个实例的类)的责任。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13564026

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档