我是否需要考虑处理任何IEnumerable <t>我使用?</t>

时间:2012-11-19 17:59:24

标签: c# linq ienumerable dispose

最近有人向我指出,各种Linq扩展方法(例如WhereSelect等)返回的IEnumerable<T>也恰好是IDisposable。以下评估结果为True

new int[2] {0,1}.Select(x => x*2) is IDisposable

我是否需要处理Where表达式的结果?

每当我调用一个返回IEnumerable<T>的方法时,我(可能)接受了在我完成后调用dispose的责任吗?

1 个答案:

答案 0 :(得分:81)

不,你不必担心这个。

它们返回IDisposable实现的事实是一个实现细节 - 这是因为C#编译器的Microsoft实现中的迭代器块碰巧创建了一个类型,它实现了两个{{ 1}}和IEnumerable<T>。后者扩展IEnumerator<T>,这就是你看到它的原因。

用于演示此示例的示例代码:

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 } } 循环会自动执行此操作。)