Dispose vs. Iterator blocks

CSJ*_*CSJ 2 c# ienumerable ienumerator dispose yield-return

这两个问题几乎可以回答我自己的问题,但并不完全.考虑这是对这些问题的后续问题.

我理解一个枚举器的foreach循环将Dispose在它完成时完成.

我的问题是:

如果有问题的枚举器实际上GetEnumerator()/yield是一个IEnumerable<T>自己实现的类的ac#iterator块(即)IDisposable,我可以确定该对象本身是否会被处理?或者我是否需要GetEnumerator()/MoveNext()/Currentusing块内明确调用?

编辑: 这个片段演示@ JonSkeet的答案.

编辑#2: 此片段基于@ JonSkeet的评论,展示了理想的用法.迭代器块负责所需资源的生命周期,而不是可枚举对象本身.这样,如果需要,可以多次枚举枚举 - 每个枚举都有自己的资源可供使用.

Ser*_*rvy 6

foreachDispose无论迭代器的实现如何,都会调用迭代器.它是否是用迭代器块创建并不重要,它的Dispose方法被调用.

这就是接口的全部要点,例如IDisposable.您不需要关心底层实现是什么.它总是处理一切.他们选择用这个电话做什么取决于他们.

至于迭代器块生成的IEnumerable<T>(不是IEnumerator<T>),它永远不会实现IDisposable,因而无法处理.如果你有一个自定义对象(而不是迭代器块)实现IEnumerable<T>IDisposable,那么就不会被布置在使用时的foreach.只有IEnumerator<T>创建的GetEnumerator将通过.