Perché lo Enumerable.SequenceEqual prende il suo confronto come IEqualityComparer? L'algoritmo sembra non fare uso di GetHashCode. Perché non prende invece un predicato Func<TSource, TSource, bool>
, simile a come First prende un Func<TSource, bool>
?Perché SequenceEqual accetta un compititore IEquality piuttosto che un predicato?
risposta
Ora che .NET Core è open source, ho inserito questa domanda come issue su GitHub. Spero che ciò si traduca in una risposta o un miglioramento.
Aggiornamento - dettagli sul possibile razionale per la progettazione esistente e le sue problematiche, tratto dal problema GitHub:
IEqualityComparer
, nonostante il nome, in realtà fa due cose: hash e controlla uguaglianza. L'unica differenza comportamentale traFunc<TSource, TSource, bool>
Func<TSource, TSource, bool>
eIEqualityComparer
èIEqualityComparer
ha un metodoGetHashCode
. Se tutto ciò che si desidera fare è controllare l'uguaglianza di sequenza, conIEqualityComparer
è necessario scrivere il codice di hashing (che può essere difficile da fare bene), anche se non sarà mai usato (ma non si può contare su non è mai stato usato perchéSequenceEqual
non documenta che non lo userà).Spesso, tipi che si confronta con
SequenceEqual
accadrà di avere uno o più tipiIEqualityComparer
compagno in modo che possano essere conservati in contenitori hash. Probabilmente, è per questo cheIEqualityComparer
è stato scelto come parametro. Tuttavia, ci sono anche un sacco di volte quando non c'è unIEqualityComparer
e non c'è un requisito di hashing . In questi casi, dover creare una classe e implementareGetHashCode
è uno spreco.
Sono tentato di dire "perché".
Se si guardano intorno ad altri metodi simili (come Enumerable.Distinct) prendono anche un IEqualityComparer
nel sovraccarico.
Inoltre, un IEqualityComparer
è il modo "corretto" per verificare se gli oggetti sono uguali. A Func<TSource, TSource, bool>
non verificherebbe necessariamente l'uguaglianza, verificherebbe se gli oggetti sono abbastanza simili per il tuo uso specifico in questo momento.
Fortunatamente è abbastanza facile creare il proprio metodo di estensione. Ad esempio, MoreLinq ha un'implementazione di DistinctBy
che puoi guardare.
'Distinct' ha bisogno di' GetHashCode' in modo che possa costruire una tabella hash per fare il confronto molti-a-molti. Altri metodi che prendono 'IEqualityComparer' sono simili. 'SequenceEqual' è" distinto ":-) in quanto è una semplice operazione lineare che non ha bisogno di una tabella hash. –
Non credo ci sia alcuna reale differenza tra abbastanza uguali e uguali al momento. –
Io sono rispettosamente in disaccordo :) SequenceEqual che entrambi gli enumerables siano della stessa lunghezza, che gli oggetti negli enumerables siano nello stesso ordine e che siano uguali. Il modo "corretto" per verificare l'uguaglianza è un paragone di uguaglianza. Se non ti interessa la "corretta uguaglianza" potresti immaginare un Enumerable.SequenceEqualTempo
- 1. Metodo C# che accetta un predicato: sembra ok?
- 2. C#: Perché LinkedList non ha un metodo RemoveAll che accetta un predicato?
- 3. Lascia che SequenceEqual funzioni per l'elenco
- 4. Un programma STL C++ che utilizza il predicato come predicato
- 5. Perché l'oggetto non ha un sovraccarico che accetta IFormatProvider?
- 6. Che cos'è un predicato in C#?
- 7. Perché Powershell pensa che sto cercando di restituire un oggetto [] piuttosto che un DataTable?
- 8. Perché Object.defineProperty() piuttosto che this.defineProperty() (per oggetti)?
- 9. Perché restituisce un elenco piuttosto che un frame o un array di dati?
- 10. Perché pop accetta un parametro in assembly?
- 11. Perché tornare const razionale piuttosto che razionale
- 12. Crea un Osservabile che accetta gli argomenti
- 13. Ruby: classe che accetta un blocco?
- 14. Posso definire dinamicamente un metodo Ruby che accetta un blocco?
- 15. Guida per spiegare perché sviluppare software su un computer fisico piuttosto che tramite un desktop remoto
- 16. dividere un iteratore da un predicato
- 17. Perché perdo millisecondi di un DateTime quando viene passato a un metodo che accetta Nullable DateTime?
- 18. Perché std :: array non ha un costruttore che accetta un valore per l'array da riempire?
- 19. Creare un metodo ruby che accetta un hash dei parametri
- 20. Come creare un Rails 4 Preoccupazione che accetta un argomento
- 21. Dichiarare un predicato dinamica gprolog
- 22. C'è un modo per negare un predicato?
- 23. Ricerca di un elemento che corrisponde al predicato in Scala
- 24. Trova l'indice di un elemento che corrisponde a un predicato in Clojure?
- 25. jQuery DataTable columnDefs bersaglio un nome piuttosto che indice
- 26. Posso definire un __repr__ per una classe piuttosto che un'istanza?
- 27. Utilizzare XML Schema di estendere un elemento piuttosto che un complexType
- 28. Perché ScheduledThreadPoolExecutor accetta solo un numero fisso di thread?
- 29. Perché la funzione std :: accetta un riferimento nella firma?
- 30. Swift: override di un inizializzatore che accetta NSinvocation
Off-topic IMO, vedere i miei commenti qui sotto. –