5

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(); 
} 

ループ内で複数の要素を見つけた後、リストの残りの部分のループを防ぐためのbreakステートメントがない理由があるかどうか知りたいです。とにかく、エラーが発生します。最初に複数のアイテムが見つかった大きなリストの場合、それは大きな違いを生むと思います。

4

1 に答える 1

7

Jon Skeetは、EduLinqブログシリーズの一部としてLINQをオブジェクトに再実装しているときにこれを見つけました

LINQ to Objectsでは、述語のないオーバーロードは2番目の要素を見つけるとすぐにInvalidOperationExceptionをスローしますが、述語のあるオーバーロードは、述語に一致する2番目の要素を見た場合でも反復を続けます。これは私にはばかげて矛盾しているようです-私はそれについてConnectの問題を開きました。何が起こるか見ていきます。

問題のConnectの問題で、Microsftは次のように述べています。

これはクリーンアップに最適であるため、述語を使用するオーバーロードを使用するときにシーケンス全体を繰り返す必要はありませんSingle。述語が指定されていない場合と同様に、2番目の一致を見つけるとすぐに失敗する可能性があります。

ただし、ここで得られるパフォーマンスの利点は Singleエラーの場合に限定されるため、この問題は現在、バグトリアージのカットラインをわずかに下回っています。Visual Studioの次のリリースでこの問題を修正するために現在追跡していないことを示すために、問題を修正しないとマークしています。バグトリアージリストで予想以上に進んだ場合、または次のリリースでバグを再検討した場合は、来年中にこのバグを再アクティブ化します。

それは2011年4月でした...

于 2013-02-18T16:12:50.563 に答える