zagnieżdżenia zwracają IEnumerable <IEnumerable <T>> z leniwą oceną

Napisałem metodę rozszerzenia LINQSplitBetween analogicznie doString.Split.

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

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

Źródło:

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

W duchu LINQ myślę, że ta metoda powinna być leniwa. Jednak,moja implementacja wykonuje leniwą ocenę na zewnętrznym IEnumerable, alenie ponad wewnętrzną niezliczoną ilością. Jak mogę to naprawić?

Pokaz, jak zewnętrzne zachowanie jest leniwe. ZałożyćThrowingEnumerable<int> jestIEnumerable<int> który eksploduje, gdy ktoś próbuje iterować nad nim (patrz Edulinq Skeeta).

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

[1,2,3]

ale wewnętrzne zachowanienie jest leniwy

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

BOOM

Spodziewamy się tutaj 1.

questionAnswers(4)

yourAnswerToTheQuestion