我真的需要 Basic 处理模式来引用其他 IDisposable 对象的类型吗?
Do I really need Basic dispose pattern for type referencing other IDisposable objects?
Microsoft design guidelines提及Dispose模式和使用场景:
DO implement the Basic Dispose Pattern on types containing instances
of disposable types. See the Basic Dispose Pattern section for details
on the basic pattern.
稍后,他们将基本处理模式显示如下:
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(bool) 只有一个参数为 true 的调用,为什么我们需要实现它?它可以很容易地简化为无参数
Dispose() {resource?.Dispose();}
。请注意,我们在这里不需要终结器,因为我们引用的对象是托管的并且有自己的终结器,所以它们不会被泄露。
- 为什么他们建议在没有终结器的情况下调用
GC.SuppressFinalize(this)
? GC 无论如何都不会调用终结器,因为它不存在!
- 我看到需要 Dispose(bool) 的唯一情况是我们确实有一些非托管引用,这些引用既不实现 IDisposable 也不实现终结器(如 this article 所示)。但是
bool disposing
的意思就是 bool includingManagedResources
。那么,为什么它的名称如此误导 'disposing' 它实际上应该做什么?
其他 class 可能继承自您的 class。考虑到派生 class 也持有非托管资源(推荐与否),这个 class 应该添加调用 Dispose(false)
的终结器。如果你的class被密封了我会同意你的看法。
因为方法 void Dispose()
不应该 virtual
遵循 Microsoft 的指南,因此派生 classes 将没有机会在处置后抑制最终确定.您的实现可能不需要终结器,但可能派生 classes 需要。
它被称为 disposing
在我看来没有特别的原因。我个人也会重命名它。
无论如何,从我的角度来看,混合拥有托管和非托管资源并不是一个好的方法。正如评论中已经提到的,甚至微软建议将非托管资源封装到托管资源中,因此您需要实现终结器的情况可能很少见。我不记得上次是什么时候自己做的了。
出于多种原因,例如误导性命名或难以理解,我也没有坚持实施指南。另一种方法是 this answer.
Microsoft design guidelines提及Dispose模式和使用场景:
DO implement the Basic Dispose Pattern on types containing instances of disposable types. See the Basic Dispose Pattern section for details on the basic pattern.
稍后,他们将基本处理模式显示如下:
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(bool) 只有一个参数为 true 的调用,为什么我们需要实现它?它可以很容易地简化为无参数
Dispose() {resource?.Dispose();}
。请注意,我们在这里不需要终结器,因为我们引用的对象是托管的并且有自己的终结器,所以它们不会被泄露。 - 为什么他们建议在没有终结器的情况下调用
GC.SuppressFinalize(this)
? GC 无论如何都不会调用终结器,因为它不存在! - 我看到需要 Dispose(bool) 的唯一情况是我们确实有一些非托管引用,这些引用既不实现 IDisposable 也不实现终结器(如 this article 所示)。但是
bool disposing
的意思就是bool includingManagedResources
。那么,为什么它的名称如此误导 'disposing' 它实际上应该做什么?
其他 class 可能继承自您的 class。考虑到派生 class 也持有非托管资源(推荐与否),这个 class 应该添加调用
Dispose(false)
的终结器。如果你的class被密封了我会同意你的看法。因为方法
void Dispose()
不应该virtual
遵循 Microsoft 的指南,因此派生 classes 将没有机会在处置后抑制最终确定.您的实现可能不需要终结器,但可能派生 classes 需要。它被称为
disposing
在我看来没有特别的原因。我个人也会重命名它。
无论如何,从我的角度来看,混合拥有托管和非托管资源并不是一个好的方法。正如评论中已经提到的,甚至微软建议将非托管资源封装到托管资源中,因此您需要实现终结器的情况可能很少见。我不记得上次是什么时候自己做的了。
出于多种原因,例如误导性命名或难以理解,我也没有坚持实施指南。另一种方法是 this answer.