2011-04-07 82 views
13

的虽然有不少Q &的作为与IDisposable要在SO发现,我暂时还没有发现一个答案:明确实施了IDisposable

我通常遵循惯例,当一个我类拥有一个IDisposable对象,那么它也执行IDisposable并在拥有的对象上调用Dispose。但是最近我遇到了一个明确实施了IDisposable的课程,因此阻止我直接调用Dispose,迫使我将其投入使用,这让我感到烦恼和不必要。

所以这个问题:为什么和什么时候会想要使用明确的接口实现IDisposable?我知道明确地实现一个接口有完美的和有效的理由,但是关于IDisposable,原因对我来说不是很清楚。

+1

这些“好的和有效的原因”是什么,为什么他们不应该支持'IDisposable'呢?为什么将一个对象投射到“IDisposable”是“烦人的”? – chiccodoro 2011-04-07 07:09:44

+2

有时,类有必要实现两个或更多个成员名称冲突的接口。对于明确的界面命名来说,这是一个很好且适当的用法。我同意OP的意见,任意命名清理方法的东西除Dispose之外是愚蠢的。即使一个类有一个Close方法,这并不意味着它也不应该有一个Dispose方法。由于在调用Close之后调用Dispose的情况最差,所以这两种方法有什么不对? – supercat 2011-04-07 07:21:41

+0

@chiccodoro:IMO显式接口实现大多在需要实现两个具有冲突成员的接口时非常有用。在任何其他情况下,如果有一个对象可以转换为接口而不是“存在”,那么该接口是不自然且令人讨厌的。 – 2011-04-07 07:22:30

回答

14

我想说除非你有一个替代的等价方法(例如关闭),否则显式实现IDisposable.Dispose是不常见的。

在这种情况下,您的包装类可以调用Close而不是cast。

一个示例是Framework < = V3.5中的WebResponse类。有趣的是在.NET 4中有一个公共的Dispose方法,所以也许微软现在已经决定明确的实现可能不是好的做法。

肖恩·法卡斯,在CLR安全团队的设计工程师中写道MSDN magazine

虽然使用块将带班的工作,确实有一个明确的IDisposable实现,我建议阶级是不会实现的接口这办法。如果你明确地实现IDisposable,开发商谁正在探索在视觉工作室使用的IntelliSense®对象模型不会注意到对象具有Dispose方法

+0

事实上,我想包装的课程暴露了我最终使用的“Close”方法。只是提供的示例代码显式包含了:'SomeClass o = new SomeClass())',因此很明显鼓励使用一次性模式。 – ChrisWue 2011-04-07 07:44:48

1

我会说这是很好的做法,它迫使(除非你想转换为IDisposable的!!)使用使用

using (ClassWithIDisposable) { 
} 

处置甚至会在出现异常的情况下,使用国际奥委会框架,如城堡,你最终不得不继承IDisposable接口统一时,被称为

而且你界面,所以它可以被调用。这些框架允许AOP,因此你没有参考你的固体类只有一个接口......

+0

using语句不适用于问题中描述的场景 - 拥有IDisposable对象的类。 – Joe 2011-04-07 07:34:23

+0

它并没有真正强制使用'using'。没有人可以阻止你做这样的事情'var o = new MyDisposable(); o.DoSomething(); return;' – ChrisWue 2011-04-07 07:34:34

+0

真的!也没有公开它......我的意思,而不是调用.Dispose()明确 – 2011-04-07 07:43:00

1

恕我直言,只有一个正确的原因,一个类明确实现IDisposable,这将是如果它是预计没有人会真的需要这样做。一个类明确实现了IDisposable的事实可以被看作是一个指标,可以安全地创建一个对象那个特定的类,尽管不一定是派生类的对象,并且在完成它时简单地抛弃它。缺少对特定类的直接可用的Dispose方法可能会被视为一个指示器,因为不需要对已知为该特定类的对象调用Dispose。

请注意,具有并使用对实现IDisposable的对象的引用,而不会意识到它的作用,这不是问题;然而,获得这样的对象的所有权。返回类型对IDisposable不起作用的工厂方法。明确地处理和实现它,但有时会返回一个期望正确处置的对象,这将成为泄漏的秘诀。如果一个类可能被用作这种工厂方法的返回类型,则不应该显式实现IDisposable。

就我个人而言,我的倾向是放弃实现IDisposable的所有对象,无论他们是否需要它。尽管如此,如果知道某些特定类型的IDisposable对象在确保妥善处置的情况下可能非常有用,否则这种情况会很困难或尴尬。