2014-04-15 14 views

risposta

1

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 tra Func<TSource, TSource, bool>Func<TSource, TSource, bool> e IEqualityComparer è IEqualityComparer ha un metodo GetHashCode. Se tutto ciò che si desidera fare è controllare l'uguaglianza di sequenza, con IEqualityComparer è 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ù tipi IEqualityComparer compagno in modo che possano essere conservati in contenitori hash. Probabilmente, è per questo che IEqualityComparer è stato scelto come parametro. Tuttavia, ci sono anche un sacco di volte quando non c'è un IEqualityComparer e non c'è un requisito di hashing . In questi casi, dover creare una classe e implementare GetHashCode è uno spreco.

1

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.

+0

'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. –

+0

Non credo ci sia alcuna reale differenza tra abbastanza uguali e uguali al momento. –

+0

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 passando in due Func (uno per T e uno per S) che selezionerebbero "qualcosa" per confrontare i due enumerabili di. Ora puoi anche controllare se le enumerables di diversi tipi sono "uguali a sufficienza". – aanund

Problemi correlati