为什么Enumerable.Range实现IDisposable?

时间:2012-07-04 03:32:05

标签: c# .net iterator idisposable resource-management

只是想知道为什么Enumerable.Range实现IDisposable

我理解为什么IEnumerator<T>会这样做,但IEnumerable<T>不需要它。


(我在使用我的.Memoise()实现时发现了这一点,该实现具有类似

的语句
if (enumerable is IDisposable)
    ((IDisposable)enumerable).Dispose();

在其“源完成”方法中,我因为好奇而放置了一个断点,并且是通过测试触发的。)

1 个答案:

答案 0 :(得分:7)

Enumerable.Range在其方法正文中使用yield returnyield 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() { }
}

结果is一个IDisposable。在此示例中,Dispose方法为空。我认为原因是没有必要处理。如果yield return包含非托管资源的类型,则可能会得到不同的编译结果。 (不确定)