[.NET] Mis interfaces favoritos: IEquatable


Seguimos con la serie de Mis Interfaces Favoritos esta vez con un interfaz bastante práctico que es IEquatable<T>. La misión de este interfaz es definir un método genérico para determinar si dos instancias de un tipo son iguales. Implícitamente se implementa los operadores de igualdad == y !=.

Para realizar correctamente la implementación de este interfaz deberemos realizar varias acciones:

  • Implementar IEquatable<T>.Equals
  • Hacer un override de System.Equals
  • Hacer un override de System.GetHashCode
  • Implementar los operadores ==, !=

Partiremos de la clase Person que creamos en el post anterior.

public class Person : IEquatable<Person>
{
   private string name;
   public string Name
   {
       get { return name; }
       set { name = value; }
   }

   private string surName;
   public string Surname
   {
       get { return surName; }
       set { surName = value; }
   }

   private int age;
   public int Age
   {
       get { return age; }
       set { age = value; }
   }

   public bool Equals(Person otherPerson)
   {
      if (otherPerson == null) return false;
         return this.Name.Equals(otherPerson.Name) &&
                 this.Surname.Equals(otherPerson.Surname) &&
                 this.Age.Equals(otherPerson.Age);
   }

   public override int GetHashCode()
   {
      return this.Name.GetHashCode()
              ^this.Surname.GetHashCode()
              ^this.Age.GetHashCode();
   }

   public override bool Equals(object obj)
   {
      Person emp = obj as Person; // realizar el casteo de tipo
      if (emp != null)
         return Equals(emp);
      else
         return false;
   }
}

Vamos a definir los operadores de igualdad dentro de nuestra clase tal y como indicamos previamente

public static bool operator ==(Person operand1, Person operand2)
{
   if (object.ReferenceEquals(operand1, operand2)) return true;
   if (object.ReferenceEquals(operand1, null)) return false;
   if (object.ReferenceEquals(operand2, null)) return false;

   return operand1.Equals(operand2);
}

public static bool operator !=(Person operand1, Person operand2)
{
   if (object.ReferenceEquals(operand1, operand2)) return false;
   if (object.ReferenceEquals(operand1, null)) return true;
   if (object.ReferenceEquals(operand2, null)) return true;

   return !operand1.Equals(operand2);
}

Ahora procederemos a realizar una aplicación de consola para revisar los conceptos aprendidos.

public class Program
{
   public static void Main(string[] args)
   {
      Person p1 = new Person() { Name = "John", Surname = "Doe", Age = 20 };
      Person p2 = new Person() { Name = "Sergio", Surname = "Parra", Age = 37 };
      Person p3 = new Person() { Name = "Sergio", Surname = "Parra", Age = 37 };

      ArrayList people = new ArrayList { p1, p2, p3 };

      Console.WriteLine($"People contains {p1.Name} {p1.Surname}: {people.Contains(p1)}");

      // Proceder a comparar objetos
      if (p1 == p2)
         Console.WriteLine($"{p1.Name} is equals than {p2.Name}");
      else
         Console.WriteLine($"{p1.Name} is different than {p2.Name}");

      if (p2 == p3)
         Console.WriteLine($"{p2.Name} is equals than {p3.Name}");
      else
         Console.WriteLine($"{p2.Name} is different than {p3.Name}");

      Console.ReadKey();
   }
}

La salida del programa sería la siguiente
People contains John Doe: True
John is different than Sergio
Sergio is equals than Sergio

Anuncios

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s