有没有办法减少IDisposable的样板代码量?

时间:2010-07-30 15:03:04

标签: .net dispose idisposable boilerplate

我的项目有很多读写器类。我开始实现IDisposable,但我相信它为我的类添加了许多样板代码。对于每个类,我需要实现:

  • 一个析构函数。
  • Dispose()方法。
  • 处置(bool处理)方法。
  • “bool dispos”字段。
  • 检查对象是否已经放置在每个公共方法上。
  • 文档(因为我启用了文档标志,编译器会发出警告)。

我的问题:

是否值得实施IDisposable?以前,我使用的课程如下:

using (Stream s = File.OpenRead("myfile.bin"))
    x = new SomethingReader(s).ReadSomething();

使用IDisposable,它没有太大改善:

using (SomethingReader r = new SomethingReader(File.OpenRead("myfile.bin")))
    x = r.ReadSomething();

我是否只能实施Dispose()方法?

我的类不使用非托管资源,因此Dispose(false)不执行任何操作。因为我正在清理的是IDisposable,所以在处理完对象之后调用我的方法应该抛出一个ObjectDisposedException,因为我使用的是已经处理好的对象。

如果您建议实施完整的IDisposable模式,有没有办法减少样板代码?

编辑:由于一些答案建议密封课程,我可以确认,实际上,通过封闭课程没有任何问题。

4 个答案:

答案 0 :(得分:2)

如果你没有直接持有非管理资源 (即使SafeHandle没有直接持有它们),那么一般来说:

  • 不要实施终结者
  • 不要实施Dispose(bool)
  • 将您的课程标记为已密封。
很可惜,多年来,所有广泛分发的IDispose文档都是针对编写互操作库的人(即.NET框架作者自己),并完全忽略了其他人的更常见的使用模式。

事情有所改善,现在fxcop(VS代码分析)认可的密封类型更轻量级模式:http://msdn.microsoft.com/en-us/library/ms244737%28VS.80%29.aspx

答案 1 :(得分:1)

如果您不使用非托管资源,则无需实现完整模式。然而,这种模式有一个好处。如果有人想扩展您的课程,他们可以覆盖Dispose(bool),然后致电base.Dispose(true)以确保所有资源都已弃置。

答案 2 :(得分:0)

假设您不需要不同的基类,则可以从Component继承。但是,如果你没有做任何太特别的事情,你可以使用Dispose方法。正如ChaosPandion所指出的那样,这可能会导致问题是其他人试图在以后扩展您的课程,因此您可能希望密封您的实现。

答案 3 :(得分:0)

如果有人试图通过重写Dispose(boolean)来扩展该类,并且您还没有实现它,那么将会失败。但如果他们尝试重写Dispose(),那就行了。如果不期望后代类直接控制任何非托管资源,我认为没有任何理由需要密封该类。