IDisposable的适当实现

4

保护自己不使用已释放的类是否有意义?我刚刚发现在我的IDisposable类的所有方法中添加了以下两行:

if (disposed)
    throw new InvalidOperationException("Attempt to use disposed object!");

那似乎不太对。


取决于您想要多安全,以及如何使用该对象。除非您在某个地方/每个地方明确处理该异常,否则它只会导致未处理的异常或一般处理的异常,在这种情况下,您最好使用在Dispose()中设置为null的对象引用异常。我认为当您不知道谁在处理已释放的对象的引用时(例如Visual Studio的自动化模型)很有用。 - Cameron
4
请注意,针对这种情况有一个专门的异常类型:ObjectDisposedException - Michael Liu
不过,你不应该将这个添加到“Dispose”方法中。预期的行为是可以多次调用对象上的“Dispose”。 - Brian Rasmussen
如果你真的想这么做,可以使用类似PostSharp的工具编写一个切面。咔嚓,零行代码。 - ta.speot.is
不,实现IDisposable接口的类应该抛出该异常。所有的.NET类都正确地执行了这一点。只有在实现终结器时才需要编写此代码。而这种情况99.99%是错误的。 - Hans Passant
2个回答

3

我的最佳答案是,这取决于具体情况。

一次性类是否仅在单个项目中使用?

  • 很可能不是(虽然对此进行断言可能并不坏)

该类是否被您或小团队之外的任何人使用?

  • 很可能是的

访问已释放对象的副作用是什么?

  • 如果它会抛出异常,则上述内容将使您在调试时更容易,但在大多数情况下,结果是相同的
  • 如果它会正常工作(即重新分配任何必要的资源等),那么谁真正关心呢
  • 如果它将导致未定义或不可预测的行为而不会抛出异常,则一定要注意,特别是如果您对上面的问题回答了“否”和“是”

0
我建议你所做的已经过度了。我同意 dkackman 的看法,你应该只为那些可能会静默失败的成员这样做,而不是全部成员都这样做。你可以像Form类一样提供一个IsDisposed属性。这样开发者就有责任自己检查对象是否已被释放了,如果他们不知道该对象是否已被释放,就需要自行进行判断。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接