我搜索了很多但却找不到这个。这就是为什么我要问如果A类继承自InterfaceA和IDisposible。那么InterfaceA是否应该从IDisposible继承是好的/必然的。
答案 0 :(得分:2)
没有
仅仅因为实现类继承自IDisposable
并不意味着它的接口应该实现IDisposable
。
IDisposable
旨在用作类释放未受管资源的方法。您的界面很可能不需要实现类来使用未受管理的资源,因此实现IDisposable
的实现没有理由。
答案 1 :(得分:2)
我认为这取决于您的预期用途。例如,如果用户永远不会看到具体的类,只看到接口,那么他们就不会期望实现实现IDisposable
。
用户可以执行以下操作:
var disposable = a as IDisposable;
if (disposable != null)
disposable.Dispose();
但我认为他们中的大多数都不会这样做,除非你的文件清楚地表明他们应该这样做。
另一方面,如果您希望用户主要直接使用该类,那么他们就会知道该类是IDisposable
,因此他们可能会正确处理它。
您在评论中提到了DI容器。这取决于特定的容器,但我认为大多数DI容器会在知道您不再使用它时处置该对象。但是这假设容器知道对象不再使用(在Castle的情况下,这很可能意味着调用Release()
)并且他们不使用“单身生活方式”(在城堡术语中)。 / p>
答案 2 :(得分:2)
接口IFoo
应该实现IDisposable
,如果持有对实现IFoo
并且需要清理的对象实例的引用的最后一个实体可能只知道该实例为IFoo
,而不是其基础类型。
例如,IEnumerator<T>
实现IDisposable
的原因是,虽然只有少数实现需要清理,但实例通常由调用IEnumerable<T>.GetEnumerator()
的代码创建。这样的代码通常对于GetEnumerator()
将要返回的实际对象类型没有任何线索;因此,它无法知道返回的对象是否需要清理。由于未能处理需要清理的枚举器可能会产生不良后果,唯一安全的假设是应尽可能清理任何未知类型的枚举器。
虽然非通用IEnumerator
未实现IDisposable
,但这并不意味着它不需要清理。相反,它意味着任何调用IEnumerable.GetEnumerator()
的代码都必须检查它返回的对象是否实现IDisposable
,如果是,Dispose
它。这是相当缓慢和麻烦的。如果IEnumerator
已实施IDisposable
,代码可以简单地调用Dispose
,无论该类是否需要清理;即使Dispose
什么也不做,在已知实现的接口上调用无操作例程将比测试未实现的接口浪费更少的时间。
重要的是要注意,即使IEnumerator
需要处理的实施很少,但是对于GetEnumerator
的未知实现调用IEnumerable
的任何代码都必须,正确性,尝试演员IDisposable
。与IEnumerable<T>
不同,IEnumerable
实现IDisposable
这一事实并未增加调用IEnumerable<T>
的代码的义务。相反,它使这些义务明确,并降低了遵守它们的成本。