IEqualityComparer<T> e tipo personalizzato
-
10-12-2019 - |
Domanda
Sto cercando di confrontare il tipo personalizzato in due List<T>
e utilizzare il Intersect
/ Except
metodo.L'uguaglianza è determinata da tre campi di questo tipo.L'uguaglianza si basa su qualcosa di più della condizione ordinaria (tutti i campi contengono gli stessi dati).Ovviamente ho implementato il file IEqualityComparer<T>
.Il mio problema è che il GetHashCode()
metodo return not equal una volta che l'hashCode non è lo stesso e questo non mi aiuta poiché non è vero nel mio caso.
Esiste un modo per confrontare due oggetti personalizzati quando l'uguaglianza si basa su più di una condizione in modo da poter utilizzare intersect/eccetto/distinto ecc...?
Ecco il mio codice:
public bool Equals(ComparableObject x, ComparableObject y)
{
if (Object.ReferenceEquals(x, null) || Object.ReferenceEquals(y, null))
return false;
if (Object.ReferenceEquals(x, y))
return true;
if (x.Var1.Equals(y.Var1) && x.Var3.Equals(y.Var3) && !x.Var2.Equals(y.Var2))
return false;
if (x.Var1.Equals(y.Var1) && !x.Var3.Equals(y.Var3) && !x.Var2.Equals(y.Var2))
return true;
if (!x.Var1.Equals(y.Var1) && x.Var3.Equals(y.Var3) && !x.Var2.Equals(y.Var2))
return false;
if (!x.Var1.Equals(y.Var1) && x.Var3.Equals(y.Var3) && x.Var2.Equals(y.Var2))
return true;
if (x.Var1.Equals(y.Var1) && !x.Var3.Equals(y.Var3) && x.Var2.Equals(y.Var2))
return false;
if (!x.Var1.Equals(y.Var1) && !x.Var3.Equals(y.Var3) && x.Var2.Equals(y.Var2))
return false;
if (!x.Var1.Equals(y.Var1) && !x.Var3.Equals(y.Var3) && !x.Var2.Equals(y.Var2))
return false;
return x.Var1.Equals(y.Var1) && x.Var1.Equals(y.Var1) && x.Var3.Equals(y.Var3);
}
public int GetHashCode(ComparableObject x)
{
return obj.Var1.GetHashCode() ^ obj.Var2.GetHashCode()^ obj.Var3.GetHashCode()
}
Soluzione
È tuo compito fornirlo GetHashCode()
che il valore restituito sarà diverso per gli oggetti that Sono diverso (nel maggior numero di casi possibile;potresti comunque restituire lo stesso codice hash per oggetti non uguali) e sarà sempre lo stesso per oggetti che Maggio essere uguale (in tutti i casi;potresti non restituire un codice hash diverso per oggetti uguali).
Ad esempio, se uno dei tre campi confrontati è an int
, puoi restituire quel campo come GetHashCode()
.
Se, tuttavia, è difficile trovare qualcosa di intelligente, puoi restituire una costante, ad esempio 42
.Da questa parte Equals()
verrà chiamato per tutte le coppie di oggetti, fornendo i risultati attesi, anche se nel modo meno performante.
Altri suggerimenti
Non sono sicuro se si dispone di altri problemi con GetHashCode nei tipi di sottostanti, ma questo è un esempio di tipo personalizzato e di un IequityComparer che restituisce true se solo i primi due campi sono gli stessi.Ciò consentirà Except
ecc. Per lavorare sul tipo.
public class CustomType
{
public int Val1 { get; set; }
public int Val2 { get; set; }
public int Val3 { get; set; }
}
class CustomTypeComparer : IEqualityComparer<CustomType>
{
public bool Equals(CustomType x, CustomType y)
{ return x.Val1 == y.Val1 && x.Val2 == y.Val2; }
public int GetHashCode(CustomType obj)
{ return obj.Val1.GetHashCode() ^ obj.Val2.GetHashCode(); }
}
.
Se le tue proprietà non sono tipi semplici come int
, è possibile utilizzare Equals()
anziché ==
per confrontare gli oggetti.