Microsoft.NET框架提供IDisposable
接口,该接口需要实现void Dispose()
方法。其目的是实现IDisposable
实现可能已分配的昂贵资源的手动或基于范围的发布。示例包括数据库集合,流和句柄。
我的问题是,如果Dispose()
方法的实现是幂等的 - 当在同一个实例上多次调用时,该实例仅被“处置”一次,并且后续调用不会抛出异常。在Java中,大多数具有相似行为的对象(作为示例再次出现流和数据库连接)对于close()
操作是幂等的,这恰好是Dispose()
方法的模拟。
但是,我个人使用.NET(特别是Windows Forms)的经验表明,并非所有实现( .NET框架本身的一部分)都是幂等的,因此后续调用这些抛出ObjectDisposedException
。这真的让我对如何处理一次性对象的实现感到困惑。该场景是否有共同的答案,还是取决于对象的具体上下文及其用法?
答案 0 :(得分:19)
如果
Dispose()
方法的实现是幂等的
是的,它应该。没有人知道它会被召唤多少次。
来自MSDN上的Implementing a Dispose Method:
Dispose方法应该可以多次调用而不会抛出异常。
具有良好实现IDispose
的对象将具有一个布尔字段标志,指示它是否已经被处理掉,并且在后续调用中什么都不做(因为它已经被处理掉了)。
答案 1 :(得分:7)
是的,当对象已被处理时,还要确保在调用类时其他方法正确响应。
public void SomeMethod()
{
if(_disposed)
{
throw new ObjectDisposedException();
}
else
{
// ...
}
}
答案 2 :(得分:5)
允许多次调用Dispose方法而不抛出异常。第一次调用后,该方法应该不执行任何操作。
答案 3 :(得分:3)
个人 - 是的 - 我总是使Dispose()具有幂等性。
在给定应用程序中对象的通常生命周期中,可能没有必要 - 从创建到处置的生命周期可能是确定性的并且是众所周知的。
然而,同样,在某些应用中,它可能不那么清楚。
例如,在装饰器场景中:我可能有一个一次性对象A,由另一个一次性对象B装饰。我可能想要显式处理A,但是B上的Dispose也可以处理它包装的实例(想想:流) )。
鉴于使Dispose幂等相对容易(即如果已经处理掉,什么也不做),看起来很愚蠢。