23

Microsoft.NET 框架提供了IDisposable需要void Dispose()方法实现的接口。其目的是启用手动或基于范围的IDisposable实现可能已分配的昂贵资源的释放。示例包括数据库集合、流和句柄。

我的问题是,该Dispose()方法的实现是否应该是幂等的——当在同一个实例上多次调用时,该实例只被“处理”一次,并且后续调用不会引发异常。在 Java 中,大多数具有相似行为的对象(我再次想到流和数据库连接作为示例)的close()操作是幂等的,这恰好是该Dispose()方法的类似物。

但是,我对 .NET(尤其是 Windows 窗体)的个人经验表明,并非所有实现(作为 .NET 框架本身的一部分)都是幂等的,因此对这些实现的后续调用会抛出ObjectDisposedException. 这真的让我对如何处理一次性对象的实现感到困惑。该场景是否有一个共同的答案,还是取决于对象的具体上下文及其用法?

4

4 回答 4

20

方法的实现是否应该Dispose()是幂等的

是的,它应该。不知道它会被调用多少次。

从在 MSDN 上实现 Dispose 方法:

Dispose 方法应该可以多次调用而不会引发异常。

一个具有良好实现的对象IDispose将具有一个布尔字段标志,指示它是否已经被释放,并且在后续调用中什么也不做(因为它已经被释放了)。

于 2012-01-19T09:45:22.577 回答
7

是的,当对象已经被释放时,还要确保类的其他方法在调用它们时正确响应。

public void SomeMethod()
{
     if(_disposed)
     {
         throw new ObjectDisposedException();
     }
     else
     {
         // ...
     }

}
于 2012-01-19T09:48:27.570 回答
5

来自 MSDN:

允许多次调用 Dispose 方法而不引发异常。该方法在第一次调用后应该什么都不做。

于 2012-01-19T09:46:12.923 回答
4

就个人而言 - 是的 - 我总是让 Dispose() 幂等。

在给定应用程序中对象的通常生命周期中,它可能不是必需的 - 从创建到处置的生命周期可能是确定性的并且众所周知。

然而,同样地,在某些应用程序中可能不是那么清楚。

例如,在装饰器场景中:我可能有一个一次性对象 A,由另一个一次性对象 B 装饰。我可能想显式处置 A,但在 B 上处置也可能处置它包装的实例(想想:流)。

鉴于使 Dispose 幂等相对容易(即,如果已经处置,则什么也不做),不这样做似乎很愚蠢。

于 2012-01-19T09:48:28.490 回答