![](/img/trans.png)
[英]Using IDisposable to unsubscribe an event— do I need to put other things inside the dispose?
[英]Do I really need Basic dispose pattern for type referencing other IDisposable objects?
Microsoft 设计指南提到了 Dispose 模式和如何使用它的场景:
务必在包含一次性类型实例的类型上实现基本处置模式。 有关基本模式的详细信息,请参阅基本处置模式部分。
后来,他们展示了基本的处置模式,如下所示:
public class DisposableResourceHolder : IDisposable {
private SafeHandle resource; // handle to a resource
public DisposableResourceHolder(){
this.resource = ... // allocates the resource
}
public void Dispose(){
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing){
if (disposing){
if (resource!= null) resource.Dispose();
}
}
}
我的问题是:
Dispose() {resource?.Dispose();}
。 注意这里我们不需要终结器,因为我们引用的对象是被管理的并且有自己的终结器,所以它们不会被泄露。GC.SuppressFinalize(this)
? GC 无论如何都不会调用终结器,因为它不存在!bool disposing
的含义将是bool includingManagedResources
。 那么为什么它被命名为对它实际上应该做的事情如此具有误导性的“处置”呢?其他类可以从您的类继承。 考虑到派生类也持有非托管资源(推荐或不推荐),这个类应该添加调用Dispose(false)
的终结器。 如果你的课是封闭的,我会同意你的。
因为方法void Dispose()
不应该是virtual
的,遵循 Microsoft 的指导方针,因此派生类将没有机会在处置后抑制终结。 您的实现可能不需要终结器,但派生类可能需要。
在我看来,这被称为没有特定原因的disposing
。 我个人也会重命名它。
无论如何,从我的角度来看,混合拥有托管和非托管资源并不是一个好方法。 正如评论中已经提到的,即使 Microsoft 建议将非托管资源封装到托管资源中,因此您需要实现终结器的情况可能很少见。 我不记得上次我自己是什么时候这样做的。
由于多种原因,例如误导性命名或因为难以理解,我也没有坚持指南中的实施。 另一种方法是这个答案。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.