foreach会自动调用Dispose吗?

jim*_*jim 58 c# foreach idisposable

在C#中,foreach是否会在任何实现IDisposable的对象上自动调用Dispose?

http://msdn.microsoft.com/en-us/library/aa664754(v=vs.71).aspx似乎表明它确实:

*否则,集合表达式是一个实现System.IEnumerable的类型,而foreach语句的扩展是:复制

IEnumerator enumerator = 
        ((System.Collections.IEnumerable)(collection)).GetEnumerator();
try {
   while (enumerator.MoveNext()) {
      ElementType element = (ElementType)enumerator.Current;
      statement;
   }
}
finally {
   IDisposable disposable = enumerator as System.IDisposable;
   if (disposable != null) disposable.Dispose();
}
Run Code Online (Sandbox Code Playgroud)

Mat*_*t H 51

是的,如果它实现了IDisposable,foreach将在枚举器上调用Dispose().

  • 如果它令人困惑,它看起来像调用枚举器本身上的dispose,而不是枚举中的项目.如果它在每个项目上调用它,那可能会破坏很多场景,并且非常难以使异常安全:) (7认同)
  • `foreach`方法只对`GetEnumerator`返回的对象执行运行时检查,看它是否实现`IDisposable`,如果该方法的返回类型是接口.否则,编译器将在编译时决定是否调用`Dispose`.特别是,如果return-type是一个不实现`IDisposable`的可继承类,则返回的对象将不会被处理*,即使它实现了`IDisposable`*. (4认同)

小智 12

这个问题/答案措辞不力.

目前尚不清楚提出的问题是:

问:"在移动到下一个之前,foreach是否处理了枚举器返回的对象?"

答:答案当然是,不.除了为枚举中的每个对象提供一次运行一些代码的便捷方法之外,它什么都不做.

或者是否意味着:

问:"在引擎盖下,foreach使用了一个可枚举的对象.即使迭代器块中有例外,它是否在调用foreach后被释放?"

答:答案是(仍然相当明显)是的!由于语法不提供对枚举数的访问,因此它有责任对其进行处理.

第二个问题的答案是出现混乱的地方,因为人们已经听说foreach用try/finally块扩展到了一段时间.最终的目的是确保枚举器在实现IDisposable时被处置.

如果您需要自己查看:请在此处查看

希望这有助于澄清!;)

  • “foreach 使用可枚举对象”是指“foreach 使用由可枚举集合提供的枚举器”。 (2认同)