我需要考虑处置任何IEnumerable <T>我使用?
最近有人向我指出,各种Linq扩展方法(如Where
, Select
等)都返回一个IEnumerable<T>
,也恰好是IDisposable
。 以下评估为True
new int[2] {0,1}.Select(x => x*2) is IDisposable
我是否需要处理Where
expression式的结果?
每当我调用一个方法返回IEnumerable<T>
,我(可能)接受负责调用处理,当我完成了它?
不,你不需要担心这个。
他们返回一个IDisposable
实现的事实是一个实现细节 – 这是因为C#编译器的Microsoft实现中的迭代器块碰巧创build了一个实现IEnumerable<T>
和IEnumerator<T>
的单一types。 后者扩展IDisposable
,这就是为什么你看到它。
示例代码来演示这一点:
using System; using System.Collections.Generic; public class Test { static void Main() { IEnumerable<int> foo = Foo(); Console.WriteLine(foo is IDisposable); // Prints True } static IEnumerable<int> Foo() { yield break; } }
请注意,您需要注意IEnumerator<T>
实现IDisposable
的事实。 所以任何时候你明确地迭代,你应该正确地处理它。 例如,如果你想迭代一些东西,并确保你总是有一个值,你可以使用如下的东西:
using (var enumerator = enumerable.GetEnumerator()) { if (!enumerator.MoveNext()) { throw // some kind of exception; } var value = enumerator.Current; while (enumerator.MoveNext()) { // Do something with value and enumerator.Current } }
(当然, foreach
循环会自动执行此操作。)