Do I need to consider disposing of any IEnumerable I use?

后端 未结 1 1574
甜味超标
甜味超标 2020-12-13 11:55

It\'s recently been pointed out to me that various Linq extension methods (such as Where, Select, etc) return an IEnumerable

相关标签:
1条回答
  • 2020-12-13 12:41

    No, you don't need to worry about this.

    The fact that they return an IDisposable implementation is an implementation detail - it's because iterator blocks in the Microsoft implementation of the C# compiler happen to create a single type which implements both IEnumerable<T> and IEnumerator<T>. The latter extends IDisposable, which is why you're seeing it.

    Sample code to demonstrate this:

    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;
        }
    }
    

    Note that you do need to take note of the fact that IEnumerator<T> implements IDisposable. So any time you iterate explicitly, you should dispose of it properly. For example, if you want to iterate over something and be sure that you'll always have a value, you might use something like:

    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
        }
    }
    

    (A foreach loop will do this automatically, of course.)

    0 讨论(0)
提交回复
热议问题