77

Where最近、さまざまなLinq拡張メソッド( 、など)が、たまたまもであるをSelect返すことが指摘されました。次のように評価しますIEnumerable<T>IDisposableTrue

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

式の結果を破棄する必要がありWhereますか?

メソッドreturningを呼び出すときはいつでもIEnumerable<T>、それが終了したときにdisposeを呼び出す責任を(潜在的に)受け入れますか?

4

1 に答える 1

91

いいえ、これについて心配する必要はありません。

それらが実装を返すという事実IDisposableは、実装の詳細です。これは、C# コンパイラの Microsoft 実装の反復子ブロックが、と の両方を実装する単一の型をたまたま作成するためです。後者は extendsです。それがあなたがそれを見ている理由です。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
    }
}

(foreachもちろん、ループはこれを自動的に行います。)

于 2012-11-19T18:02:27.153 に答える