Плохая реализация Enumerable.Single?

Я наткнулся на эту реализацию в Enumerable.cs с помощью отражателя.

public static TSource Single<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate)
{
    //check parameters
    TSource local = default(TSource);
    long num = 0L;
    foreach (TSource local2 in source)
    {
        if (predicate(local2))
        {
            local = local2;
            num += 1L;
            //I think they should do something here like:
            //if (num >= 2L) throw Error.MoreThanOneMatch();
            //no necessary to continue
        }
    }
    //return different results by num's value
}

Я думаю, что они должны разорвать цикл, если есть более двух элементов, удовлетворяющих условию, почему они всегда проходят цикл коллекция? В случае, если этот отражатель неправильно дизассемблирует dll, я пишу простой тест:

class DataItem
{
   private int _num;
   public DataItem(int num)
   {
      _num = num;
   }

   public int Num
   {
      get{ Console.WriteLine("getting "+_num); return _num;}
   }
} 
var source = Enumerable.Range(1,10).Select( x => new DataItem(x));
var result = source.Single(x => x.Num < 5);

Я думаю, что для этого тестового случая он напечатает «получение 0, получение 1», а затем выдаст исключение. Но правда в том, что он продолжает «получать 0 ... получать 10» и выдает исключение. Есть ли какая-то алгоритмическая причина, по которой они реализуют этот метод таким образом?

РЕДАКТИРОВАТЬ Некоторые из вас думали, что это из-за побочных эффектов выражения предиката , после глубоких размышлений и некоторых тестовых примеров у меня есть вывод о том, что побочные эффекты в данном случае не имеют значения . Если вы не согласны с этим выводом, приведите пример.

34
задан Cheng Chen 31 January 2011 в 04:57
поделиться