0Pricing
C# Academy · Lección

Implementación de IEquatable

Proporcione igualdad con seguridad de tipos mediante Equals.

Implementación de IEquatable es una lección gratuita de C# Academy en CoddyKit. Esta es la lección 1 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de C# Academy, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de C# Academy incluye 4 lecciones en total.

¿Por qué IEquatable<T>?

IEquatable<T> proporciona un método Equals(T other) con tipado fuerte. Evita el boxing en los tipos de valor y las conversiones de tipo en los tipos de referencia, lo que hace que la igualdad sea más rápida y clara.

Implementación de la interfaz

Implemente IEquatable<T> y proporcione Equals(T other). También debe invalidar el object.Equals heredado y GetHashCode para mantener la coherencia en todas las formas de comparación.

using System;

public struct Point : IEquatable<Point>
{
    public int X, Y;
    public Point(int x, int y) { X = x; Y = y; }

    public bool Equals(Point other) => X == other.X && Y == other.Y;
    public override bool Equals(object obj) => obj is Point p && Equals(p);
    public override int GetHashCode() => HashCode.Combine(X, Y);
}

public class Program
{
    public static void Main()
    {
        Console.WriteLine(new Point(1, 2).Equals(new Point(1, 2)));
    }
}

Evite el boxing en las estructuras

El método no genérico object.Equals(object) convierte en boxing el argumento de una estructura. El método tipado Equals(Point other) de IEquatable<T> recibe la estructura directamente, por lo que no se produce ninguna asignación.

using System;

public struct Point : IEquatable<Point>
{
    public int X, Y;
    public Point(int x, int y) { X = x; Y = y; }
    public bool Equals(Point other) => X == other.X && Y == other.Y; // no boxing
    public override bool Equals(object obj) => obj is Point p && Equals(p);
    public override int GetHashCode() => HashCode.Combine(X, Y);
}

public class Program
{
    public static void Main()
    {
        Point a = new Point(3, 4);
        Point b = new Point(3, 4);
        Console.WriteLine(a.Equals(b)); // calls the typed overload
    }
}

Las colecciones utilizan IEquatable<T>

List<T>.Contains, Dictionary y HashSet prefieren IEquatable<T>.Equals cuando está disponible. Implementarlo hace que estas operaciones sean eficientes y correctas para su tipo.

using System;
using System.Collections.Generic;

public struct Point : IEquatable<Point>
{
    public int X, Y;
    public Point(int x, int y) { X = x; Y = y; }
    public bool Equals(Point other) => X == other.X && Y == other.Y;
    public override bool Equals(object obj) => obj is Point p && Equals(p);
    public override int GetHashCode() => HashCode.Combine(X, Y);
}

public class Program
{
    public static void Main()
    {
        var list = new List<Point> { new Point(0, 0), new Point(1, 1) };
        Console.WriteLine(list.Contains(new Point(1, 1)));
    }
}

Tipos de referencia e IEquatable<T>

Las clases también pueden implementar IEquatable<T>. El método Equals tipado evita una conversión de tipo, y usted gestiona explícitamente null para el parámetro de referencia.

using System;

public class Person : IEquatable<Person>
{
    public string Name;
    public Person(string name) { Name = name; }

    public bool Equals(Person other) => other != null && other.Name == Name;
    public override bool Equals(object obj) => Equals(obj as Person);
    public override int GetHashCode() => Name?.GetHashCode() ?? 0;
}

public class Program
{
    public static void Main()
    {
        Console.WriteLine(new Person("Ada").Equals(new Person("Ada")));
        Console.WriteLine(new Person("Ada").Equals((Person)null));
    }
}

Envíe object.Equals al método tipado

Un patrón claro consiste en escribir la comparación una sola vez en Equals(T) y hacer que object.Equals delegue en ella. Así se garantiza que ambos se comporten de forma idéntica.

using System;

public struct Id : IEquatable<Id>
{
    public int Value;
    public Id(int value) { Value = value; }
    public bool Equals(Id other) => Value == other.Value;
    public override bool Equals(object obj) => obj is Id other && Equals(other);
    public override int GetHashCode() => Value;
}

public class Program
{
    public static void Main()
    {
        object boxed = new Id(5);
        Console.WriteLine(boxed.Equals(new Id(5)));
    }
}

Compare varios campos

En los tipos con varios campos, compárelos todos en Equals. Dos instancias son iguales solo si coinciden todos los campos relevantes.

using System;

public struct DateRange : IEquatable<DateRange>
{
    public int Start, End;
    public DateRange(int start, int end) { Start = start; End = end; }
    public bool Equals(DateRange other) => Start == other.Start && End == other.End;
    public override bool Equals(object obj) => obj is DateRange d && Equals(d);
    public override int GetHashCode() => HashCode.Combine(Start, End);
}

public class Program
{
    public static void Main()
    {
        Console.WriteLine(new DateRange(1, 5).Equals(new DateRange(1, 5)));
        Console.WriteLine(new DateRange(1, 5).Equals(new DateRange(1, 6)));
    }
}

Combínelo con operadores

Combine IEquatable<T> con == y != para que quienes utilicen el tipo puedan comparar con cualquiera de las dos sintaxis, respaldadas por la misma comparación tipada.

using System;

public struct Money : IEquatable<Money>
{
    public decimal Amount;
    public Money(decimal a) { Amount = a; }
    public bool Equals(Money other) => Amount == other.Amount;
    public override bool Equals(object obj) => obj is Money m && Equals(m);
    public override int GetHashCode() => Amount.GetHashCode();
    public static bool operator ==(Money a, Money b) => a.Equals(b);
    public static bool operator !=(Money a, Money b) => !a.Equals(b);
}

public class Program
{
    public static void Main()
    {
        Console.WriteLine(new Money(9.99m) == new Money(9.99m));
    }
}

Los registros lo implementan automáticamente

Un record de C# genera automáticamente IEquatable<T>, Equals basado en valores y GetHashCode. Cuando solo necesita igualdad por valor, un registro evita escribir código repetitivo.

using System;

public record Point(int X, int Y);

public class Program
{
    public static void Main()
    {
        var a = new Point(1, 2);
        var b = new Point(1, 2);
        Console.WriteLine(a.Equals(b));
        Console.WriteLine(a == b);
    }
}

Cuándo implementarlo manualmente

Implemente IEquatable<T> manualmente cuando necesite reglas de igualdad personalizadas, como nombres que no distingan mayúsculas de minúsculas o ignorar determinados campos, que un registro no puede expresar directamente.

using System;

public class CaseInsensitiveTag : IEquatable<CaseInsensitiveTag>
{
    public string Name;
    public CaseInsensitiveTag(string name) { Name = name; }
    public bool Equals(CaseInsensitiveTag other)
        => other != null && string.Equals(Name, other.Name, StringComparison.OrdinalIgnoreCase);
    public override bool Equals(object obj) => Equals(obj as CaseInsensitiveTag);
    public override int GetHashCode() => Name?.ToLowerInvariant().GetHashCode() ?? 0;
}

public class Program
{
    public static void Main()
    {
        Console.WriteLine(new CaseInsensitiveTag("Red").Equals(new CaseInsensitiveTag("RED")));
    }
}

Póngalo en práctica

Implemente IEquatable<T> para un tipo de referencia pequeño y haga que todas las formas de comprobar la igualdad pasen por el método tipado.

using System;
using System.Collections.Generic;

public class Coordinate : IEquatable<Coordinate>
{
    public int Lat, Lng;
    public Coordinate(int lat, int lng) { Lat = lat; Lng = lng; }
    public bool Equals(Coordinate other) => other != null && other.Lat == Lat && other.Lng == Lng;
    public override bool Equals(object obj) => Equals(obj as Coordinate);
    public override int GetHashCode() => HashCode.Combine(Lat, Lng);
}

public class Program
{
    public static void Main()
    {
        var set = new HashSet<Coordinate> { new Coordinate(10, 20) };
        Console.WriteLine(set.Contains(new Coordinate(10, 20)));
    }
}

Comprobación rápida

Recuerde la ventaja de IEquatable.

Resumen

IEquatable<T> proporciona igualdad con seguridad de tipos.

  • Proporciona Equals(T other), lo que evita el boxing en las estructuras y las conversiones de tipo en las clases.
  • Las colecciones lo prefieren para realizar búsquedas correctas y eficientes.
  • Haga que object.Equals y los operadores pasen por el método tipado.
  • Los registros lo implementan automáticamente; impleméntelo manualmente para reglas personalizadas.

Preguntas frecuentes

¿La lección «Implementación de IEquatable» es gratis?

Sí — el texto completo de «Implementación de IEquatable» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de C# Academy, actualiza a CoddyKit PRO. El curso de C# Academy incluye 4 lecciones en total.

¿Qué aprenderé en «Implementación de IEquatable»?

Proporcione igualdad con seguridad de tipos mediante Equals. Practicas C# Academy con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.

¿Necesito experiencia previa para empezar C# Academy?

No se requiere experiencia previa. C# Academy en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 1 de 4.

¿Cuánto tiempo toma la lección «Implementación de IEquatable»?

La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.

¿Puedo escribir y ejecutar código en esta lección de C# Academy?

Sí. Cada lección de C# Academy incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.

Todas las lecciones de este curso

  1. Implementación de IEquatable
  2. Sobrescritura de GetHashCode
  3. Implementación de IComparable
  4. IComparer para ordenación personalizada
← Volver a C# Academy