2011-12-15 7 views
5

Aquí está el comparador de igualdad que acabo de escribir porque quería un conjunto distinto de elementos de una lista que contiene entidades.Preguntas sobre 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. ¿Por qué Distinct requieren un comparador en contraposición a un Func<T,T,bool>?
  2. ¿Están (A) y (B) algo distinto a las optimizaciones, y hay situaciones en las que no actuarían de la manera esperada, debido a la sutileza en la comparación de referencias?
  3. Si quisiera, podría reemplazar a (C) con

    return GetHashCode(x) == GetHashCode(y)

+0

observación aleatoria autoevaluada: esto podría hacer una buena consulta –

Respuesta

4
  1. Por lo tanto, se puede utilizar hashcodes a ser O (n) en contraposición a O (n )
  2. (A) es una optimización.
    (B) es necesario; de lo contrario, arrojaría un NullReferenceException. Si Invoice es una estructura, sin embargo, ambos son innecesarios y más lento.
  3. hashcodes no son únicos
+0

mi cerebro no funciona: pensé que leí en los documentos que "los objetos iguales devuelven códigos hash iguales" ... –

+0

@Gabriel: objetos desiguales _can_ también devuelve igual hashcodes. – SLaks

1
  • A es una manera simple y rápida para asegurar que tanto los objetos que se encuentran en la misma dirección de memoria por lo que ambas referencias mismo objeto.
  • B - si una de las referencias es nulo - obviuosly que no tiene ningún sentido hacer la igualdad comparación
  • C - no, a veces GetHashCode() puede devolver el mismo valor para diferentes objetos (hash collision) por lo que debe hacer la comparación igualdad

en cuanto al mismo valor de código hash para diferentes objetos, MSDN:

Si dos objetos resultan ser iguales, el método GetHashCode por cada objeto debe devolver el mismo valor. Sin embargo, si dos objetos no se comparan como , los métodos GetHashCode para los dos objetos no deben devolver valores diferentes.

0

Distinct() básicamente funciona con el término "no igual". por lo tanto, si su lista contiene tipos no primitivos, debe implementar su propio EqualityComparer.

En A, puede comprobar si los objetos son idénticos o no. Si dos objetos son iguales, no tienen que ser idénticos, pero si son idénticos, puede estar seguro de que son iguales. Entonces, la parte A puede aumentar la efectividad del método en algunos casos.

Cuestiones relacionadas