гнездо возвращает IEnumerable> с ленивой оценкой

Я написал метод расширения LINQ SplitBetween, аналогичный String.Split.

> new List<int>(){3,4,2,21,3,2,17,16,1}
>.SplitBetween(x=>x>=10)

[3,4,2], [3,2], [], [1]

Источник:

// partition sequence into sequence of contiguous subsequences
// behaves like String.Split
public static IEnumerable<IEnumerable<T>> SplitBetween<T>(this IEnumerable<T> source, 
                                                          Func<T, bool> separatorSelector, 
                                                          bool includeSeparator = false)
{
    var l = new List<T>();
    foreach (var x in source)
    {
        if (separatorSelector(x))
        {
            if (includeSeparator)
            {
                l.Add(x);
            }
            yield return l;
            l = new List<T>();
        }
        else
        {
            l.Add(x);
        }
    }
    yield return l;
}

В духе LINQ я думаю, что этот метод должен выполнять ленивую оценку. Однако моя реализация выполняет ленивую оценку внешнего IEnumerable, но не внутреннего IEnumerable. Как я могу это исправить?

Демонстрация того, насколько внешнее поведение лениво. Предположим, что ThrowingEnumerable<int>— это IEnumerable<int>, который взрывается, когда кто-либо пытается перебрать его (, см. Edulinq Скита ).

(new List<int>(){1,2,3,10,1})
.Concat(Extensions.ThrowingEnumerable<int>())
.SplitBetween(x=>x>=10)
.First().ToList();

[1,2,3]

но внутреннее поведение не ленивое

(new List<int>(){1,2,3,10,1})
.Concat(Extensions.ThrowingEnumerable<int>())
.SplitBetween(x=>x>=10)
.ElementAt(2).First();

BOOM

Мы ожидаем 1 здесь.

13
задан nawfal 17 February 2013 в 19:58
поделиться