2013-02-18 7 views
5

Hier ist der Code der SingleOrDefault Funktion extrahiert:Optimierung in der SingleOrDefault Funktion von Linq

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

Ich frage mich, zu wissen, ob es einen Grund gibt, warum nach dem in der Schleife mehr als ein Element zu finden, da ist keine break-Anweisung, die das Schleifen der restlichen Liste verhindert. In jedem Fall wird ein Fehler auftreten. Für eine große Liste, wo am Anfang mehr als ein Artikel gefunden wird, denke ich, würde es einen Unterschied machen.

+0

Wo erhalten Sie den Code? Dekompilierte? –

+0

Wenn Sie sich ansehen, dass die Überladung kein Prädikat verwendet, werden Sie sehen, dass sie für IList optimiert ist und nur zwei Elemente enthält. Ich nehme an, der Fehlerfall ist nicht wichtig zu optimieren – adrianm

+0

@HamletHakobyan Ja, ich habe Resharper verwendet. – Samuel

Antwort

7

Jon Skeet found this while reimplementing LINQ to objects as part of his EduLinq blog series:

Es stellt sich heraus, dass auf Objekte in LINQ, die Überlastungen ohne Prädikat werfen InvalidOperationException, sobald sie ein zweites Element zu sehen, aber die Überlastung mit einem Prädikat auch immer laufen, wenn sie habe ein zweites Element gesehen, das einem Prädikat entspricht. Das scheint mir lächerlich widersprüchlich zu sein - ich habe eine Connect-Frage dazu gestellt; mal sehen was passiert.

Im Connect issue in question, Microsft sagen:

Das wäre toll, zu reinigen, so dass die gesamte Sequenz iterieren ist nicht erforderlich, wenn die Single Überlastung verwenden, die ein Prädikat nimmt - wir konnten scheitern schnell bei der Suche nach einer zweiten Übereinstimmung, ähnlich wie wenn kein Prädikat angegeben ist.

Da jedoch der perf Vorteil hier Single ‚s Fehlerfall beschränkt würde werden mußte, dieses Problem zur Zeit fällt knapp unter unserer Bug Triage Schnittlinie. Wir markieren das Problem nicht behoben, um anzuzeigen, dass wir nicht verfolgen, um dieses Problem in der nächsten Version Visual Studio zu beheben. Wir werden diesen Fehler im nächsten Jahr wieder aktivieren, wenn wir weiter als erwartet durch unsere Fehler Triage Liste erhalten, oder wenn wir den Fehler für die folgende Version erneut besuchen.

Das im April 2011 war ...

+0

Vielen Dank. Nachdem ich die Implementierung von Jon Skeet betrachtet habe, sage ich meinen Mitarbeitern, dass dies die Implementierung ist, nach der ich vor ein paar Stunden gesucht habe. – Samuel