Is there ever a reason to not use 'yield return' when returning an IEnumerable?

One clear reason to not use an enumerator is when you need IEnumerator<>.Reset() to work.

Iterators are very nice, but they can't escape the "there's no free lunch" principle. You won't find them used in the .NET framework collection code. There's a good reason for that, they can't be as efficient as a dedicated implementation. Now that mattered to the .NET designers, they couldn't predict when efficiency matters. You can, you know whether your code is in the critical path of your program.

Iterators are a bit over twice as slow as a dedicated implementation. At least that's what I measured by testing the List<> iterator. Watch out for micro optimizations, they are still really fast and their big Oh is the same.

I'll include the testing code so you can verify this for yourself:

using System;
using System.Collections.Generic;
using System.Diagnostics;

class Program {
    static void Main(string[] args) {
        var lst = new MyList<int>();
        for (int ix = 0; ix < 10000000; ++ix) lst.Add(ix);
        for (int test = 0; test < 20; ++test) {
            var sw1 = Stopwatch.StartNew();
            foreach (var item in lst) ;
            sw1.Stop();
            var sw2 = Stopwatch.StartNew();
            foreach (var item in lst.GetItems()) ;
            sw2.Stop();
            Console.WriteLine("{0} {1}", sw1.ElapsedMilliseconds, sw2.ElapsedMilliseconds);
        }
        Console.ReadLine();

    }
}

class MyList<T> : IList<T> {
    private List<T> lst = new List<T>();

    public IEnumerable<T> GetItems() {
        foreach (T item in lst)
            yield return item;
    }

    public int IndexOf(T item) { return lst.IndexOf(item); }
    public void Insert(int index, T item) { lst.Insert(index, item); }
    public void RemoveAt(int index) { lst.RemoveAt(index); }
    public T this[int index] {
        get { return lst[index]; }
        set { lst[index] = value; }
    }
    public void Add(T item) { lst.Add(item); }
    public void Clear() { lst.Clear(); }
    public bool Contains(T item) { return lst.Contains(item); }
    public void CopyTo(T[] array, int arrayIndex) { lst.CopyTo(array, arrayIndex); }
    public int Count { get { return lst.Count; } }
    public bool IsReadOnly { get { return ((IList<T>)lst).IsReadOnly; } }
    public bool Remove(T item) { return lst.Remove(item); }
    public IEnumerator<T> GetEnumerator() { return lst.GetEnumerator(); }
    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { return GetEnumerator(); }
}

Odd question. If your method is returning an IEnumerable that it gets from somewhere else, then obviously it won't be using yield return. If your method needs to assemble a concrete data structure representing the results in order to perform some manipulation on it before returning, then I guess you won't use yield return there either.


Iterator blocks perform a "live" evaluation each time they are iterated.

Sometimes, however, the behavior you want is for the results to be a "snapshot" at a point in time. In these cases you probably don't want to use yield return, but instead return a List<> or Set, or some other persistent collection instead.

It's also unnecessary to use yield return if you're dealing with query objects directly. This is often the case with LINQ queries - it's better to just return the IEnumerable<> from the query rather than iterating and yield returning results yourself. For example:

var result = from obj in someCollection
             where obj.Value < someValue
             select new { obj.Name, obj.Value };

foreach( var item in result )
   yield return item; // THIS IS UNNECESSARY....

// just return {result} instead...