Linq的SingleOrDefault函数的优化

Sam*_*uel 5 c# linq optimization

以下是SingleOrDefault函数的代码提取:

public static TSource SingleOrDefault<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate) { 
    if (source == null) throw Error.ArgumentNull("source");
    if (predicate == null) throw Error.ArgumentNull("predicate");
    TSource result = default(TSource);
    long count = 0; 
    foreach (TSource element in source) {
        if (predicate(element)) { 
            result = element; 
            checked { count++; }
        } 
    }
    switch (count) {
        case 0: return default(TSource);
        case 1: return result; 
    }
    throw Error.MoreThanOneMatch(); 
} 
Run Code Online (Sandbox Code Playgroud)

我想知道在循环中找到多个元素之后是否有任何原因,没有break语句来阻止循环列表的其余部分.无论如何,会发生错误.对于在开头找到多个项目的大型列表,我认为它会产生不同的影响.

Aak*_*shM 7

Jon Skeet 在重新实现LINQ to objects时发现了这一点,作为他的EduLinq博客系列的一部分:

事实证明,在LINQ to Objects中,没有谓词的重载只要看到第二个元素就会抛出InvalidOperationException,但是带谓词的重载即使在他们看到第二个元素与谓词匹配时也会继续迭代.这看起来很荒谬 - 我已经打开了一个关于它的Connect问题; 我们会看到会发生什么.

在有问题Connect问题中,Microsft说:

清理起来非常好,因此在使用Single带谓词的重载时不需要迭代整个序列- 我们可以在找到第二个匹配时快速失败,类似于未指定谓词时的操作.

但是,由于此处的性能优势仅限于 Single错误情况,因此该问题目前仅落在我们的错误分类切割线下方.我们正在将问题标记为Not not Fix,以表明我们目前尚未跟踪在Visual Studio的下一版本中修复此问题.如果我们通过错误分类列表得到超出预期的,或者如果我们重新审视以下版本的错误,我们将在明年重新激活此错误.

那是2011年4月......