2012-02-22 13 views
5

Ho bisogno di eseguire l'hash su una variabile membro invece della classe, quindi non controllo se il riferimento è nel dizionario. Senza sovrascrivere i valori predefiniti, non troverà un identico Value, ma restituirà solo se trova la stessa identica istanza di HashedType, in modo tale che questo codice non riesca.Vantaggio di derivare la classe esterna da IEqualityComparer <> override di GetHashCode e uguale a

Dictionary.Add(new HashedType(4)); 
Dictionary.Contains(new HashedType(4)); // fails to find 4 

Definizione HashedType:

HashedType 
{ 
    public HashedType(Int32 value) { Value = value); } 
    public HashedType(String value) { Value = value); } 
    public object Value; 
    public void Serialize(Serializer s) 
    { 
     if (Value.GetType() == typeof(Int32)) 
     { 
     s.Set<Int32>(0); 
     s.Set<Int32>(Value); 
     } 
     else 
     { 
     s.Set<Int32>(1); 
     s.Set<String>(Value); 
     } 

    } 
} 

Sembra che posso ignorare GetHashCode() e Equals() per fare questo per me.

Tuttavia, MSDN consiglia di creare una classe separata derivata da IEqualityComparer e di istanziare i miei dizionari utilizzati HashedType con HashedTypeComparer: IEqualityComparer.

per contribuire a rendere questo più facile, ho derivato da dizionario e creato

HashedTypeDictionary<U> : Dictionary<T,U> 
{ 
    public HashedTypeDictionary() : base(new HashedTypeComparer()) { } 
    public bool Equals(HashedType a, HashedType b) { return a.Value == b.Value; } 
    publci int GetHashCode(HashedType a) { return a.Value.GetHashCode(); } 
} 

tutto questo sembra artificioso.

L'unico vantaggio che ottengo non è la modifica di Equals()?

Voglio dire, davvero parlando, vorrei uguagliare confrontare uguali contro quel singolo membro.

risposta

4

L'idea è che object.Equals è l'uguaglianza naturale per quel tipo (e GetHashCode dovrebbe corrispondere a tale idea di uguaglianza). IEqualityComparer viene utilizzato quando si desidera un'eguaglianza diversa caso per caso.

Considerare ad esempio un string. I metodi sostituiti da Equals & GetHashCode eseguono confronti con distinzione tra maiuscole e minuscole. Ma cosa succede se si desidera un dizionario in cui le chiavi non siano case-sensitive? Scrivi IEqualityComparer che non è sensibile al maiuscolo e al minuscolo e passalo nel costruttore del dizionario.

Gli esempi sembrano come se due istanze di HashedType dovessero essere trattate normalmente come uguali se i loro membri sono uguali. In tal caso, ti consigliamo di ignorare i metodi object.Equals e object.GetHashCode e non scrivere un numero IEqualityComparer.

3

La ragione per cui scegliere l'una rispetto all'altra è se si sempre si desidera confrontare le istanze di un determinato tipo utilizzando una determinata logica o solo in questa situazione.

Equals e GetHashCode forniscono la "vera" attuazione se due oggetti sono logicamente uguali. IEqualityComparer consente di ignorare quello in base a caso per caso e separare la proprietà (potrebbero essere diverse parti che controllano le entità rispetto al codice che le utilizza).

0

Se la maggior parte delle volte si desidera che il comportamento del dizionario funzioni automaticamente, sostituisce GetHashCode ed Equals. Tenete presente che, affinché funzioni, non devono mai cambiare durante il ciclo di vita dell'oggetto, quindi se si sta eseguendo il valore, è necessario impostare Valore nel costruttore e una proprietà di sola lettura.

IEqualityComparer è davvero utilizzato quando si desidera confrontare le cose in modo diverso in una sezione del programma.

2

Immaginate, per un momento, di non possedere il proprio della classe sottostante (vale a dire che è prodotto da un'altra squadra o dato solo a voi come binario). È sempre possibile creare il IEqualityComparer. Potresti non avere la possibilità di modificare Equals e GetHashCode ...

Problemi correlati