2013-02-14 9 views
6

Mi chiedo quali regole ci sono per dire se una parte del codice LINQ soffre di doppia enumerazione?Come si può sapere se un metodo di estensione LINQ soffre di doppia enumerazione?

Ad esempio, quali sono i segni indicanti che il seguente codice potrebbe essere il doppio enumerazione? Quali sono altri segni da tenere d'occhio?

public static bool MyIsIncreasingMonotonicallyBy<T, TResult>(this IEnumerable<T> list, Func<T, TResult> selector) 
    where TResult : IComparable<TResult> 
{ 
    return list.Zip(list.Skip(1), (a, b) => selector(a).CompareTo(selector(b)) <= 0).All(b  => b); 
} 
+2

Probabilmente il fatto che si accede 'list' e applicare un metodo LINQ to più di una volta. Inoltre, ReSharper ha una bella ispezione che ti avvisa di questo. –

+1

In questo caso, ti stai chiaramente riferendo a 'list' due volte, e entrambi i tuoi usi di' list' finiscono per costringerlo ad essere enumerato. Ma non sono affatto sicuro che questa sia una buona spiegazione. – hvd

+1

Se stai chiedendo se ci sono comportamenti generali che verrebbero associati a "Double Enumeration", posso dirti che non ce n'è. Poiché IEnumerable è un'interfaccia e qualsiasi comportamento dipenderebbe in gran parte dall'implementazione dell'IEnumerable. – Aron

risposta

7

Passo in uno di questi:

public class OneTimeEnumerable<T> : IEnumerable<T> 
{ 
    public OneTimeEnumerable(IEnumerable<T> source) 
    { 
    _source = source; 
    } 

    private IEnumerable<T> _source; 
    private bool _wasEnumerated = false; 

    public IEnumerator<T> GetEnumerator() 
    { 
    if (_wasEnumerated) 
    { 
     throw new Exception("double enumeration occurred"); 
    } 
    _wasEnumerated = true; 
    return _source.GetEnumerator(); 
    } 

} 
+0

Assolutamente geniale. – Contango

Problemi correlati