有什么方法可以减少 IDisposable 的样板代码量吗?
我的项目有许多读者和作家课程。我开始实现 IDisposable,但我相信它向我的类添加了许多样板代码。对于每个类,我需要实现:
- 析构函数。
- 一个 Dispose() 方法。
- 一个 Dispose(bool disducing) 方法。
- “布尔处理”字段。
- 检查该对象是否已在每个公共方法上释放。
- 文档(因为我启用了文档标志并且编译器否则发出警告)。
我的问题:
是否值得实现 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();
< strong>我可以只实现 Dispose() 方法吗?
我的类不使用非托管资源,因此 Dispose(false) 不执行任何操作。由于我正在清理的也是 IDisposable,因此在对象被处置后调用我的方法应该会抛出 ObjectDisposeException,因为我使用的是已处置的对象。
如果您建议实现完整的 IDisposable 模式,有什么方法可以减少样板代码吗?
编辑:由于一些答案建议密封该类,我可以确认,事实上,密封班级没有任何问题。
My project has many reader and writer classes. I started implementing IDisposable, but I believe that it adds many boilerplate code to my classes. For each of the classes, I need to implement:
- A destructor.
- A Dispose() method.
- A Dispose(bool disposing) method.
- A "bool disposed" field.
- A check to see if the object is already disposed on every single public method.
- Documentation (since I have the documentation flag enabled and the compiler warns otherwise).
My questions:
Is it worth to implement IDisposable? Previously, I used my classes like:
using (Stream s = File.OpenRead("myfile.bin"))
x = new SomethingReader(s).ReadSomething();
With IDisposable, it doesn't improve much:
using (SomethingReader r = new SomethingReader(File.OpenRead("myfile.bin")))
x = r.ReadSomething();
Can I ONLY implement the Dispose() method?
My class doesn't use unmanaged resources, so Dispose(false) does nothing. Since what I'm cleaning is IDisposable too, suposedly calling my methods after the object has been disposed should throw a ObjectDisposedException since I'm using an already disposed object.
If you recommend implementing the full IDisposable pattern, is there any way to reduce the boilerplate code?
EDIT: Since some answers recommend sealing the class, I can confirm that, in fact, there isn't any problem by sealing the class.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
如果您不直接持有非托管资源(即,即使 SafeHandle 也不直接持有它们),那么一般来说:
非常遗憾的是,多年来,所有广泛分发的 IDispose 文档都是为编写互操作库的人(即 .NET 框架作者本身)而设计的,而完全忽略了其他人更常见的使用模式。
情况有所改善,现在 fxcop(VS 代码分析)可以识别密封类型的更轻量级模式:http://msdn.microsoft.com/en-us/library/ms244737%28VS.80%29.aspx
If you're not holding unmanaged resources directly (i.e. even SafeHandle is not holding them directly), then in general:
It is a great pity that for years all the widely distributed documentation for IDispose was intended for people writing interop libraries (i.e. the .NET framework authors themselves), and completely ignored a much more common usage pattern for everyone else.
Things have improved, and there is now a more lightweight pattern recognised by fxcop (VS Code Analysis) for sealed types: http://msdn.microsoft.com/en-us/library/ms244737%28VS.80%29.aspx
如果您不使用非托管资源,则无需实现完整模式。然而,这种模式有一个副作用。如果有人想要扩展您的类,他们可以覆盖
Dispose(bool)
,然后调用base.Dispose(true)
以确保所有资源都已释放。You do not need to implement the full pattern if you are not using unmanaged resources. There is however one side benefit to the pattern. If someone wants to extend your class they can override
Dispose(bool)
and then callbase.Dispose(true)
to make sure all resources are disposed.您可以继承 组件 假设您不这样做需要不同的基类。但是,如果您没有做任何特别的事情,您可以只使用
Dispose
方法。作为 ChaosPandion 指出这可能会导致问题,因为其他人稍后会尝试扩展您的类,因此您可能需要密封您的实现。You could inherit from Component assuming you don't need a different base class. But, if you aren't doing anything too special you could just use the
Dispose
method. As ChaosPandion pointed out this could cause problems is someone else tries to extend your class later so you may want to seal your implementations.如果有人尝试通过重写 Dispose(boolean) 来扩展该类,而您尚未实现它,那将会失败。但如果他们尝试重写 Dispose(),那就会起作用。如果不希望后代类直接控制任何非托管资源,我看不出有任何理由需要密封该类。
If someone tries to extend the class by overriding Dispose(boolean) and you haven't implemented it, that will fail. But if they try overriding Dispose(), that will work. I don't see any reason the class should need to be sealed if one doesn't expect descendant classes to directly control any unmanaged resources.