所有类都应该实现IDisposable接口吗?

3

(非常新手问题)

我可能误解了这一点,但在MSDN上,我相信它说在编写每个类时实现Dispose析构函数是一个好的习惯。我是否应该(您是否应该)真的在编写每个类时实现IDisposable接口?

另外,实现接口的正确语法是将“Implements”关键字放在“class”声明后面的一行吗?我把它放在与“class”同一行上,但出现了错误。

还有一个问题:在编写由接口实现的方法时,是否必须遵循以下语法,例如:

Public Sub Dispose() Implements IDisposable.Dispose

我对上面的代码很好奇,是否需要将实现的方法声明为 "Implements System.IDisposable.Dispose"。

1
快速回答你最后两个问题:Implements(和Inherits)必须在类体内单独一行声明实现的接口(和继承的类),而方法声明中的Implements必须在同一行,对于任何实现接口的方法都是必需的(即使其名称匹配)。 - Pavel Minaev
1
快速回答:不是所有类都应该实现IDisposable,MSDN也没有告诉你要这样做。长话短说- https://dev59.com/P3RB5IYBdhLWcg3w1Kv0 - Pavel Minaev
@Preet 这不是那个C#问题的副本。这是一个VB.Net问题;400_the_cat还没有意识到您必须在方法行上编写“实现 blah”。这使其显式和隐式实现,您可以直接调用Dispose或先转换为IDisposable - MarkJ
在 MSDN 的哪里,您认为它说实现每个类中的 Dispose 析构函数是一个好的实践? - Mark Hurd
4个回答

10

只有当你的类持有其他实现了 IDisposable 接口的类的实例,或者它持有本地资源时,才应该实现 IDisposable 接口。

欲了解更多信息,请参见此文章


3
不应该。只有在直接使用非托管资源或具有实现IDisposable的成员并希望确保在调用类的dispose方法时调用它们的dispose方法时,才应实现IDisposable。

如果类或接口是为了继承而设计的,并且可能会由工厂方法返回类或接口类型,该工厂方法有时会生成需要清理的对象。一个主要的例子是IEnumerator<T>。即使实现IEnumerator<T>的99.9%的类不需要清理,任何能够接受任意IEnumerable<T>并调用其上的GetEnumerator的代码必须正确地在返回的枚举器上调用Dispose。如果不这样做,不能合法地接受所有类型的IEnumerable<T> - supercat
请注意,非泛型的IEnumerator没有实现IDisposable但它应该实现,因为可以接受任意IEnumerable的任何代码都可以调用它的GetEnumerator,为了正确性,需要检查返回的枚举器是否实现了IDisposable,如果是,则进行处理。*即使99.9%实现IEnumerator的类不需要清理,这也是必需的。 IEnumerator不实现IDisposable并不会减轻调用者的任何责任-它只是使他们更难承担责任。 - supercat

2
许多计算机可能执行的操作都会产生需要进行“清理”操作的平衡。例如,打开文件的操作会创建关闭文件的需求。使用调制解调器拨打电话会创建断开连接的需求。执行操作而不执行所需的平衡清理有时可能是无害的,但有时可能会在计算机或现实世界中产生严重后果(在用户弹出介质之前未关闭文件可能会导致文件损坏和数据丢失;未终止调制解调器连接可能会使某人多花费许多美元的电话费)。
IDisposable的目的是提供一种方法,以便行为良好的程序可以确保执行任何需要执行的清理操作。执行必须通过清理来平衡的操作的任何例程都应该保留执行此类清理所需的信息和动力,直到执行此类清理为止;如果例程不能在返回调用者之前执行此类清理,则应该 (1) 将信息提供给调用者,并记录为要求调用者使用该信息来执行清理,或者 (2) 将必要的信息保存在一个或多个字段中,并实现IDisposable;当调用IDisposable.Dispose时,对象应该使用保存的信息来执行清理。
请注意,仅当请求创建IDisposable对象的任何对象接受并遵守确保调用对象的IDisposable.Dispose方法的责任时,IDisposable才能正常工作。系统确实提供了一种称为终结的“备份”手段,对象可以使用它来确保它们有机会执行清理。基本上,一个对象向系统注册一个请求,该请求说“让我知道我是否被遗弃了”。如果系统检测到一个对象已被抛弃,它将尝试给对象一个机会执行任何必要的清理。请注意,系统可能需要一段时间才能注意到一个对象已被抛弃,并且由于各种原因,通知可能并不总是发生。在对象被遗弃之前调用IDisposable.Dispose通常比依赖于“最后机会”的终结机制要好得多。

0

.Net框架有垃圾回收机制,大部分情况下会为您管理内存的分配和释放(创建新对象时)。然而,您还需要管理非托管资源(也可以称为本地资源)。因此,垃圾收集器不再足够好,您需要使用IDisposable接口来管理内存。一个很好的例子是创建数据访问层,其中处理数据库连接并使用IDisposable接口。

请查看以下链接以了解如何实现iDisposable接口: https://msdn.microsoft.com/zh-cn/library/498928w2(v=vs.110).aspx


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