Esta pagina se ve mejor con JavaScript habilitado

How to: Encontrar elementos duplicados con IEqualityComparer<T> y el método Except<T> de LinQ

 ·  ☕ 2 minutos lectura  ·  ✍️ Saturnino Pimentel

Dando una vuelta por stackoverflow he visto una pregunta en la cual deseaban obtener los elementos de una colección siempre y cuando los identificadores no coincidieran con los de una segunda colección y que no se realizaran modificaciones a su entidad, la clase que proponían como ejemplo es la siguiente.

1
2
3
4
5
6
public class Employee
{
  //EmployeeNumber cannot be the same as the Id
  public int EmployeeNumber {get; set; }
  public string EmployeeName {get; set }
}

Nota: recuerda que las clases personalizadas son tipos por referencia y los objetos aun cuando contengan los mismos datos no tienen la misma referencia en memoria (es decir Equals para este escenario no es una opción).

Pensando un poco y tomando en cuenta que lo que las colecciones estaban en memoria les he sugerido implementar la interfaz IEqualityComparer < T > y el método Except< T >.

La interfaz IEqualityComparer nos permite comparar dos objetos de una manera sencilla y con las condiciones que nosotros queramos, IEqualityComparer contiene los siguientes dos métodos:

  • public bool Equals(Employee x, Employee y) Este método nos va a permitir determinar si el objeto es igual.
  • public int GetHashCode(Employee x) Va a retornar un código hash para el objeto en específico.

Pues bien, como el problema que se ha planteado al inicio necesitaba comparar los identificadores la implementación de la interfaz ha quedado de la siguiente manera (puedes adaptarla a tus necesidades).

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
public class MyComparer : IEqualityComparer<Employee>
{
    public bool Equals(Employee x, Employee y)
    {
        return x.EmployeeNumber.Equals(y.EmployeeNumber);
    }

    public int GetHashCode(Employee x)
    {
        return x.EmployeeNumber.GetHashCode()
    }
}

Una vez tenemos nuestra implementación podemos hacer uso del método Except de LinQ y obtener los elementos de nuestra lista sin tomar en cuenta los que tengan el mismo identificador de la segunda lista, algo que en teoría de conjuntos es conocido como la diferencia.

Tendrías que implementar un código parecido al siguiente:

1
IEnumerable<Employee> except =list1.Expect(list2,new MyComparer());

Hasta aquí este post corto, espero les resulte de utilidad.
¡Saludos!

compartir en

Saturnino Pimentel
Escrito por
Saturnino Pimentel
Software developer