IEnumerableを破棄することを検討する必要があるか 使用していますか?質問する

IEnumerableを破棄することを検討する必要があるか 使用していますか?質問する

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もちろん、ループはこれを自動的に実行します。)

おすすめ記事