我注意到通用的IEnumerator<T>
继承自 IDisposable,但非泛型接口 IEnumerator 则不继承。为什么要这样设计呢?
通常,我们使用foreach语句来遍历IEnumerator<T>
实例。 foreach 的生成代码实际上有一个 try-finally 块,它在 finally 中调用 Dispose() 。
Basically it was an oversight. In C# 1.0, foreach
never called Dispose
1. With C# 1.2 (introduced in VS2003 - there's no 1.1, bizarrely) foreach
began to check in the finally
block whether or not the iterator implemented IDisposable
- they had to do it that way, because retrospectively making IEnumerator
extend IDisposable
would have broken everyone's implementation of IEnumerator
. If they'd worked out that it's useful for foreach
to dispose of iterators in the first place, I'm sure IEnumerator
would have extended IDisposable
.
然而,当 C# 2.0 和 .NET 2.0 出现时,它们有了一个新的机会——新的接口、新的继承。扩展接口更有意义IDisposable
这样你就不需要在finally块中进行执行时检查,现在编译器知道迭代器是否是一个IEnumerator<T>
它可以发出无条件调用Dispose
.
编辑:这对于Dispose
在迭代结束时调用(无论如何结束)。这意味着迭代器可以保留资源 - 这使得它可以逐行读取文件。迭代器块生成Dispose
确保任何实施finally
与迭代器的“当前执行点”相关的块在其被释放时执行 - 因此您可以在迭代器中编写正常的代码,并且应该适当地进行清理。
1 Looking back at the 1.0 spec, it was already specified. I haven't yet been able to verify this earlier statement that the 1.0 implementation didn't call Dispose
.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)