对于实现IDisposable的正确方式,我有一些挥之不去的疑问。考虑下面的场景...
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中),但我似乎找不到正确的构建方式的具体示例。
发布于 2012-11-26 20:15:01
~Bar() {
Dispose(false);
}每当你发现自己在写这样的代码时,先深呼吸一下,问一问“我真的需要终结器吗?”(do actually need a finalizer)?极少需要终结器,只有当您自己获得非托管资源的所有权时,才需要终结器。
第一个试金石测试是“do The finalizer actually do?”如果你遵循代码,那就很清楚了。它调用Dispose(false),只有当参数为true时,代码才会执行某些操作。接下来的事情就是你不需要aa finalizer。这是完全正常的,终结器是微软担心的东西。他们编写了包装非托管资源的.NET框架类。FileStream,Socket,等等。最重要的是SafeHandle类,旨在包装操作系统句柄。他们有自己的终结器,你不需要自己重写。
因此,如果没有终结器,代码将完全折叠为简单而正确的实现,您只需调用您自己存储的任何可处理对象的Dispose()方法:
public class Bar : IDisposable {
private readonly Foo MyFoo;
public Bar() {
this.MyFoo = new Foo();
}
public void Dispose() {
MyFoo.Dispose();
}
}发布于 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方法是调用者(更具体地说是创建了一个实例的类)的责任。
https://stackoverflow.com/questions/13564026
复制相似问题