如果结构可以实现IDisposable,为什么他们不能有析构函数?

时间:2018-05-02 10:30:16

标签: c# destructor idisposable finalizer

我读了类似question的接受答案,部分答案是:

  

当结构作为参数传递时,它们通过值传递:它们   被复制。现在你有两个具有相同内部字段的结构,   他们都打算试图清理同一个物体。一   将首先发生,所以之后使用另一个的代码   将开始神秘地失败...然后它自己的清理将失败

同样的问题不适用于Dispose()吗?如果结构可以实现IDisposable,那么不允许它们使用终结器的原因是什么?

如果终结者的整个要点是调用Dispose(false)以防程序员忘记调用Dispose(),并且结构可以有IDisposable.Dispose(),那么为什么不允许结构的终结器但是允许它们对于参考类型?

2 个答案:

答案 0 :(得分:2)

因为IDisposable只是一个界面。它没有特殊的处理方式。结构可以实现接口,因此它们可以实现IDisposable

然而,这并不意味着它没有任何意义。 IDisposable的目的是释放非托管资源。结构可以具有引用到非托管资源,并且将受益于Dispose(不用说,该引用本身应该实现IDisposable并具有终结器)。

作为奖励,Dispose通常用作using模式的一部分。您只为using块创建实例,在Dispose之前保留引用,不涉及任何奇怪。真的,没有理由禁止这样做。

答案 1 :(得分:2)

  

这个问题不适用于Dispose()吗?

排序,但不完全。具体而言,"然后它自己的清理将失败"是可能但不太可能,因为Dispose()必须安全地在同一个对象上多次调用,并且在同一对象的不同副本上多次调用它通常不会有问题。

  

如果结构不能有终结器,为什么允许它们实现IDisposable

允许它是自然行为;它为语言提供了更简单的规则。由于这不是程序员偶然可能出错的原因,因此在编译器中编写额外代码以拒绝这一点的好处很小。

Jeroen Mostert补充说,它甚至可以使结构实现IDisposable很有意义:

IDisposable可能只是因为它是某些其他代码的要求而实现,即使Dispose()在此特定类型上的实现绝对不会做任何事情。在这种情况下,不会意外地在另一个副本上调用它。一个示例是当结构实现IEnumerator<T>时,IEnumerator<T>依次实现IDisposable