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()
}
È stato utile?

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.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top