简体   繁体   中英

Why does Enumerable.Range Implement IDisposable?

Just wondering why Enumerable.Range implements IDisposable .

I understand why IEnumerator<T> does, but IEnumerable<T> doesn't require it.


(I discovered this while playing with my .Memoise() implementation, which has statement like

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

in its "source finished" method that I had placed a breakpoint on out of curiousity, and was triggered by a test.)

Enumerable.Range uses yield return in its method body. The yield return statement produces an anonymous type that implements IDisposable , under the magic of the compiler, like this:

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

After being compiled, there is an anonymous nested class like this:

[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() { }
}

so the result is a IDisposable . In this example, the Dispose method leaves empty. I think the reason is that there is nothing need to be disposed. If you yield return a type that contains unmanaged resources, you may get a different compiling result. (NOT SURE about it)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM