Oggetto di confronto in .net
-
12-10-2019 - |
Domanda
E 'diverso dal punto di vista CLR per implementare IEqualityComparer
vs sovrascrivendo l'operatore ==
per la proprietà si usa nel IEqualityComparer<T>
? E se sì, quando si usa uno contro l'altro?
Modifica
Ok ha senso che l'IEqaulityComparer utilizzato dai implementazioni di Hashtable - è scivolato fuori dalla mia mente quando mi è stato la pubblicazione della domanda. E per quanto riguarda le estensioni di Linq di IEnumerable. Questo significa che .net costruisce un Hashtable durante l'esecuzione di questo tipo di metodi di estensione?
Soluzione
IEqualityComparer
non è equal
, uguale è per oggetto (metodo di istanza), ma EqualityComparer è per la decorazione, per esempio in LINQ si vuole fare specifico distinto:
personList.OrderBy(p=>p.ID).Distinct(new MyEqualityComparer())
e
class MyEqualityComparer: IEqualityComparer<Person>
{
public bool Equals(Person p1, Person p2)
{
if (p1.Age == p2.Age)
return true;
return false;
}
public int GetHashCode(Person p)
{
return p.Id.GetHashCode();
}
}
ma uguali è per Persona:
public class Person
{
public int ID{get;set;}
public int Age{get;set;}
public override bool Equals(object o)
{
//do stuff
}
}
È possibile effettuare una serie di decorazioni da IEqualityComparer ma non si può fare questo metodo di istanza (si può scrivere personList.Distinct (nuova AnotherComparer), ...)
Altri suggerimenti
IEqualityComparer è utilizzato dal Hashtable , NameValueCollection e OrderedDictionary classi al fine di sostenere una definizione personalizzata di 'uguaglianza' per i tipi. Ecco perché fornisce GetHashCode () , che non ha molto a che fare con l'uguaglianza per se .
Se non si fornisce un IEqualityComparer
, le classi di cui sopra si imposterà a Object.Equals () , che implementa l'uguaglianza di riferimento . Un operator ==
sovraccarico non sarà chiamato in quel contesto.
EDIT: i metodi di estensione Alcuni di LINQ effettivamente avuto un IEqualityComparer
come argomento, ma il principio rimane lo stesso: se tale argomento non viene specificato, il metodo finirà confrontando riferimenti, non i valori, e operator ==
non sarà chiamato.
IEqualityComparer
viene utilizzato ad esempio per il confronto in Dictionary<TK,TV>
.
E 'completamente diverso da quello delle operatore ==
perché in realtà Dictionary
(e in generale tutto ciò che uso IEqualityComparer
) non fa alcuna chiamata all'operatore ==
.
Al massimo, è possibile confrontare "attuazione IEqualityComparer
" vs "sovrascrivendo GetHashCode
e Equals
metodi", perché in realtà si tratta di due modi per ottenere la stessa cosa (e vorrei dire che sono uguali a me).