我读了类似question的接受答案,部分答案是:
当结构作为参数传递时,它们通过值传递:它们 被复制。现在你有两个具有相同内部字段的结构, 他们都打算试图清理同一个物体。一 将首先发生,所以之后使用另一个的代码 将开始神秘地失败...然后它自己的清理将失败
同样的问题不适用于Dispose()
吗?如果结构可以实现IDisposable
,那么不允许它们使用终结器的原因是什么?
如果终结者的整个要点是调用Dispose(false)
以防程序员忘记调用Dispose()
,并且结构可以有IDisposable.Dispose()
,那么为什么不允许结构的终结器但是允许它们对于参考类型?
答案 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
。