2010-06-23 7 views
3

J'ai écrit une méthode d'extension LINQ personnalisée qui étend la méthode TakeWhile() pour qu'elle soit inclusive, plutôt qu'exclusive lorsque le prédicat est faux.Custom Inclusive TakeWhile(), existe-t-il un meilleur moyen?

 public static IEnumerable<T> TakeWhile<T>(this IEnumerable<T> source, Func<T, bool> predicate, bool inclusive) 
     { 
      source.ThrowIfNull("source"); 
      predicate.ThrowIfNull("predicate"); 

      if (!inclusive) 
       return source.TakeWhile(predicate); 

      var totalCount = source.Count(); 
      var count = source.TakeWhile(predicate).Count(); 

      if (count == totalCount) 
       return source; 
      else 
       return source.Take(count + 1); 
     } 

Bien que cela fonctionne, je suis sûr qu'il existe une meilleure façon de le faire. Je suis assez sûr que cela ne fonctionne pas en termes d'exécution différée/chargement.

ThrowIfNull() est une méthode d'extension pour vérifier ArgumentNullException

la communauté peut-elle fournir des conseils ou des réécritures? :)

Répondre

10

Vous avez raison; ceci n'est pas favorable à l'exécution différée (l'appel Count requiert une énumération complète de la source).

Vous pouvez cependant faire:

public static IEnumerable<T> TakeWhile<T>(this IEnumerable<T> source, Func<T, bool> predicate, bool inclusive) 
{ 
    foreach(T item in source) 
    { 
     if(predicate(item)) 
     { 
      yield return item; 
     } 
     else 
     { 
      if(inclusive) yield return item; 

      yield break; 
     } 
    } 
} 
+0

Excellent! Une solution beaucoup plus agréable que le mien :) –

+0

C'est magnifique. –

+0

C'est fantastique. Surtout quand vous avez besoin d'un TakeWhile avec une logique inversée, c'est-à-dire prendre tout alors que le prédicat est 'false'. – silkfire