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
- 1. Warum ein SWITCH ... CASE nicht "char" nimmt?
- 2. warum nimmt ein Volladdierer 3 Zahlen auf und nicht 2
- 3. Warum Haskell ein Argument nimmt
- 4. Pass generic EquaityComparer mit SequenceEqual
- 5. Warum nimmt Moose's Builder einen String-Wert?
- 6. Warum nimmt `execvp` ein` char * const argv [] `?
- 7. IEqualityComparer funktioniert nicht wie vorgesehen
- 8. Warum gibt es keine Linq-Methode, um eindeutige Werte durch ein Prädikat zurückzugeben?
- 9. Warum wird mein Prädikat nicht zurückverfolgt?
- 10. Warum nimmt Python lxml meine XML nicht?
- 11. Implementieren IEqualityComparer
- 12. Warum nimmt JavaScript diesen Fehler nicht auf?
- 13. Warum nimmt RazorViewEngine meine DisplayTemplate nicht an?
- 14. Warum funktioniert dieses Prolog-Prädikat?
- 15. Dictionary-Objekt nicht Prädikat
- 16. Warum nimmt der Compiler an, dass malloc einen int zurückgibt?
- 17. IEqualityComparer für Annoymous Typ
- 18. Warum nimmt strchr einen int, damit der char gefunden wird?
- 19. Warum nimmt TaskSpawn statt void *?
- 20. Wie implementieren Sie einen IEqualityComparer <T> in VB.NET?
- 21. Wie kann ich in Haskell ein m-ary-Prädikat und ein n-ary-Prädikat nehmen und ein (m + n) -äres Prädikat konstruieren?
- 22. Warum nimmt der Postfix-Inkrementoperator einen Dummy-Parameter an?
- 23. Warum nimmt pop einen Parameter in der Baugruppe?
- 24. Können Sie einen zusätzlichen Parameter an ein Prädikat übergeben?
- 25. Vergleich Arrays Inhalt, Differenz von SequenceEqual und StructuralComparisons.StructuralEqualityComparer
- 26. Ransack Gem wählen Prädikat und benutzerdefinierte Prädikat Namen
- 27. IEqualityComparer für anonymen Typ
- 28. Warum nimmt TR keinen Stil?
- 29. Warum nimmt Stream.Write kein UInt?
- 30. Warum Prädikat- und Nichtprädikatversionen für generische Algorithmen unterscheiden?
Off-Topic IMO, siehe meine Kommentare unten. –