2013-02-14 79 views
6

我想知道是否有什么规则要告诉如果一部分LINQ代码遭受双重枚举?如何判断一个LINQ扩展方法是否遭受双重枚举?

例如,以下代码可能是双枚举的告示符号是什么?还有什么其他迹象要注意?

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

可能是你访问'list'和应用LINQ方法将其不止一次的事实。此外,ReSharper有一个很好的检查,提醒你这一点。 – 2013-02-14 23:31:56

+1

在这种情况下,您明确提到'list'两次,并且'list'的两个用法都会强制它被枚举。但我完全不相信这是一个很好的解释。 – hvd 2013-02-14 23:32:14

+1

如果你问是否有任何与“双枚举”相关的一般行为,我可以告诉你没有。由于IEnumerable是一个接口,任何行为都将高度依赖于IEnumerable的实现。 – Aron 2013-02-15 02:56:23

回答

7

通在其中的一个:

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

绝对的辉煌。 – Contango 2013-02-15 11:12:02