Warum nimmt Enumerable.SequenceEqual seinen Vergleich als IEqualityComparer? Der Algorithmus scheint GetHashCode nicht zu verwenden. Warum nimmt es nicht stattdessen ein Func<TSource, TSource, bool>
Prädikat, ähnlich wie First ein Func<TSource, bool>
nimmt?Warum nimmt SequenceEqual einen IEqualityComparer und nicht ein Prädikat?
Antwort
Nun, da .NET Core Open Source ist, habe ich diese Frage als issue auf GitHub veröffentlicht. Hoffentlich wird das zu einer Antwort oder Verbesserung führen.
Update - Details über die möglichen Gründe für das bestehende Design und seine Probleme, aus der Ausgabe GitHub genommen:
IEqualityComparer
, trotz seines Namen, sind wirklich zwei Dinge: Hashes und prüft, ob Gleichberechtigung. Der einzige Verhaltensunterschied zwischen einerFunc<TSource, TSource, bool>
und einerIEqualityComparer
ist, dassIEqualityComparer
eineGetHashCode
Methode hat. Wenn alles, was Sie tun möchten, ist auf Gleichheit der Reihenfolge zu überprüfen, mitIEqualityComparer
müssen Sie schreiben Sie den Hash-Code (was kann schwierig zu tun), obwohl wird es wahrscheinlich nie verwendet werden (aber Sie können nicht darauf zählen es wird nie verwendet, weilSequenceEqual
nicht dokumentiert, dass es es nicht verwenden wird).Oft Typen, die Sie mit
SequenceEqual
vergleichen passieren werden ein oder mehrIEqualityComparer
Begleiter Typen haben, so dass sie in gehasht Behältern gelagert werden können. Wahrscheinlich wurde deshalbIEqualityComparer
als Parameter gewählt. Allerdings gibt es auch viele Male , wenn es keineIEqualityComparer
gibt und es keine Hashing Anforderung gibt. In diesen Fällen ist das Erstellen einer Klasse und das Implementieren vonGetHashCode
verschwenderisch.
Ich bin versucht zu sagen "weil".
Wenn Sie sich auf andere ähnliche Methoden (wie Enumerable.Distinct) schauen, nehmen sie auch eine IEqualityComparer
in der Überlastung.
Auch eine IEqualityComparer
ist die "richtige" Möglichkeit zu prüfen, ob Objekte gleich sind. A Func<TSource, TSource, bool>
würde nicht unbedingt auf Gleichheit prüfen, es würde prüfen, ob die Objekte zu diesem Zeitpunkt für Ihre spezifische Nutzung ähnlich genug sind.
Zum Glück ist es einfach genug, Ihre eigene Erweiterungsmethode zu machen. Zum Beispiel hat eine Implementierung von DistinctBy
, die Sie betrachten können.
'Distinct' benötigt' GetHashCode', damit es eine Hash-Tabelle erstellen kann, um den Viele-zu-Viele-Vergleich durchzuführen. Andere Methoden, die IEqualityComparer verwenden, sind ähnlich. 'SequenceEqual' ist" distinct ":-), da es sich um eine einfache lineare Operation handelt, die keine Hash-Tabelle benötigt. –
Ich glaube nicht, dass es im Moment einen wirklichen Unterschied zwischen Gleichem und Gleichem gibt. –
stimme ich nicht zu :) SequenceEqual beide, dass beide Aufzählungen von gleicher Länge sind, dass die Objekte in den Aufzählungen in der gleichen Reihenfolge sind, und dass sie gleich sind. Der "richtige" Weg, um auf Gleichheit zu prüfen, ist ein Gleichheitsvergleicher. Wenn Sie "richtige Gleichheit" nicht interessieren, könnten Sie sich eine Enumerable.SequenceEqualEnough
Off-Topic IMO, siehe meine Kommentare unten. –