2011-12-15 10 views
5

Ecco il comparatore di uguaglianza che ho appena scritto perché volevo un insieme distinto di elementi da un elenco contenente entità.Domande su IEqualityComparer <T>/List <T> .Distinct()

class InvoiceComparer : IEqualityComparer<Invoice> 
    { 
     public bool Equals(Invoice x, Invoice y) 
     { 
      // A 
      if (Object.ReferenceEquals(x, y)) return true; 

      // B 
      if (Object.ReferenceEquals(x, null) || Object.ReferenceEquals(y, null)) return false; 

      // C 
      return x.TxnID == y.TxnID; 
     } 

     public int GetHashCode(Invoice obj) 
     { 
      if (Object.ReferenceEquals(obj, null)) return 0; 
      return obj.TxnID2.GetHashCode(); 
     } 
    } 
  1. Perché Distinct richiede un operatore di confronto in contrapposizione ad un Func<T,T,bool>?
  2. Sono (A) e (B) qualcosa di diverso dalle ottimizzazioni e ci sono scenari in cui non agiscono nel modo previsto, a causa della sottigliezza nel confronto dei riferimenti?
  3. Se avessi voluto, avrei potuto sostituire (C) con

    return GetHashCode(x) == GetHashCode(y)

+0

casuale auto-agrandizing osservazione: questo potrebbe fare un buon esame quetion –

risposta

4
  1. Così può utilizzare codici hash per essere O (n) al contrario di O (n )
  2. (A) è un ottimizzazione.
    (B) è necessario; altrimenti, genererebbe un NullReferenceException. Se Invoice è una struttura, tuttavia, sono entrambi non necessari e più lento.
  3. No. codici hash non sono univoci
+0

il mio cervello non funziona: ho pensato che avrei letto nei documenti che "oggetti uguali Codici di ritorno pari hash" ... –

+0

@Gabriel: oggetti disuguali _potete_ anche restituire hash code uguali. – SLaks

1
  • A è un modo semplice e rapido che entrambi gli oggetti situati allo stesso indirizzo di memoria in modo che entrambi i riferimenti allo stesso oggetto.
  • B - se uno dei riferimenti è nullo - obviuosly non ha alcun senso fare uguaglianza confronto
  • C - no, a volte GetHashCode() può restituire lo stesso valore per gli oggetti differenti (hash collision) così si dovrebbe fare confronto di uguaglianza

quanto riguarda lo stesso valore del codice hash per diversi oggetti, MSDN:

Se due oggetti risultano uguali, il metodo GetHashCode per ogni 01 L'oggettodeve restituire lo stesso valore. Tuttavia, se due oggetti non corrispondono a confronto , i metodi GetHashCode per i due oggetti non devono restituire valori diversi da .

0

Distinto() funziona fondamentalmente sul termine "non uguale". pertanto, se il tuo elenco contiene tipi non primitivi, devi implementare il tuo EqualityComparer.

In A, verifichi se gli oggetti sono identici o meno. Se due oggetti sono uguali, non devono essere identici, ma se sono identici, puoi essere certo che sono uguali. Quindi la parte A può aumentare l'efficacia del metodo in alcuni casi.

Problemi correlati