Where
最近、さまざまなLinq拡張メソッド( 、Select
など)が を返すが、IEnumerable<T>
それが でもあることが指摘されましたIDisposable
。次の式は と評価されます。True
new int[2] {0,1}.Select(x => x*2) is IDisposable
式の結果を破棄する必要がありますかWhere
?
を返すメソッドを呼び出すたびにIEnumerable<T>
、終了時に dispose を呼び出す責任を (潜在的に) 受け入れていることになりますか?
ベストアンサー1
いいえ、心配する必要はありません。
実装を返すという事実はIDisposable
実装の詳細です。これは、C#コンパイラのMicrosoft実装の反復ブロックが、シングル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
。したがって、明示的に反復処理するたびに、それを適切に破棄する必要があります。たとえば、何かを反復処理して、常に1つの値として、次のようなものを使用できます。
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
もちろん、ループはこれを自動的に実行します。)