This would be most effectively implemented manually, as far as I can tell, to make sure that he will not list more than necessary.
public static IEnumerable<TSource> TakeWhileOrFirst<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate) { using (var enumerator = source.GetEnumerator()) { if (!enumerator.MoveNext()) yield break; TSource current = enumerator.Current; yield return current; if (predicate(current)) { while (enumerator.MoveNext() && predicate(current = enumerator.Current)) yield return current; } } }
And for the sake of completion, an overload including an index:
public static IEnumerable<TSource> TakeWhileOrFirst<TSource>(this IEnumerable<TSource> source, Func<TSource, int, bool> predicate) { using (var enumerator = source.GetEnumerator()) { if (!enumerator.MoveNext()) yield break; TSource current = enumerator.Current; int index = 0; yield return current; if (predicate(current, index++)) { while (enumerator.MoveNext() && predicate(current = enumerator.Current, index++)) yield return current; } } }
source share