11

なぜEnumerable.Range実装するのか疑問に思っていますIDisposable

IEnumerator<T>理由はわかりますが、IEnumerable<T>必須ではありません。


(これは、次のようなステートメントを持つ.Memoise()実装で遊んでいるときに発見しました。

if (enumerable is IDisposable)
    ((IDisposable)enumerable).Dispose();

不思議なことにブレークポイントを設定し、テストによってトリガーされた「ソース終了」メソッドで。)

4

1 に答える 1

7

Enumerable.Rangeyield returnメソッド本体で使用します。このステートメントは、コンパイラの魔法の下で、次のようにyield return実装する匿名型を生成します。IDisposable

static IEnumerable<int> GetNumbers()
{
    for (int i = 1; i < 10; i += 2)
    {
        yield return i;
    }
}

コンパイル後、次のような匿名のネストされたクラスがあります。

[CompilerGenerated]
private sealed class <GetNumbers>d__0 
   : IEnumerable<int>, IEnumerable, IEnumerator<int>, IEnumerator, IDisposable
{
    //the implementation
    //note the interface is implemented explicitly
    void IDisposable.Dispose() { }
}

したがって、結果isIDisposable。この例では、Disposeメソッドは空のままです。その理由は、処分する必要がないからだと思います。yield return管理されていないリソースを含むタイプの場合、異なるコンパイル結果が得られる可能性があります。(それについてはよくわかりません)

于 2012-07-04T03:49:21.197 に答える