Implementazione di IEquatable
Fornisca un'uguaglianza indipendente dal tipo con Equals.
Implementazione di IEquatable è una lezione C# Academy gratuita su CoddyKit. Questa è la lezione 1 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento C# Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso C# Academy include 4 lezioni in totale.
Perché IEquatable<T>?
IEquatable<T> fornisce un metodo Equals(T other) fortemente tipizzato. Evita il boxing per i tipi valore e i cast per i tipi riferimento, rendendo l'uguaglianza più veloce e chiara.
Implementare l'interfaccia
Implementi IEquatable<T> e fornisca Equals(T other). Dovrebbe anche eseguire l'override di object.Equals e GetHashCode ereditati, per mantenere coerenti tutti i percorsi.
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)));
}
}Evitare il boxing per le struct
Il metodo non generico object.Equals(object) esegue il boxing dell'argomento struct. Il metodo tipizzato Equals(Point other) fornito da IEquatable<T> riceve direttamente la struct, quindi non viene effettuata alcuna allocazione.
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
}
}Le raccolte usano IEquatable<T>
List<T>.Contains, Dictionary e HashSet preferiscono IEquatable<T>.Equals quando disponibile. Implementarlo rende queste operazioni efficienti e corrette per il Suo 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)));
}
}Tipi riferimento e IEquatable<T>
Anche le classi possono implementare IEquatable<T>. Il metodo Equals tipizzato evita un cast e consente di gestire esplicitamente null per il parametro di tipo riferimento.
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));
}
}Instradare object.Equals attraverso il metodo tipizzato
Un modello pulito consiste nello scrivere il confronto una sola volta in Equals(T) e nel fare in modo che object.Equals deleghi a quel metodo. Questo garantisce che entrambi si comportino in modo identico.
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)));
}
}Confrontare più campi
Per i tipi con più campi, li confronti tutti in Equals. Due istanze sono uguali solo se tutti i campi rilevanti corrispondono.
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)));
}
}Abbinare gli operatori
Combini IEquatable<T> con == e !=, così gli utenti possono confrontare i valori con entrambe le sintassi, entrambe basate sullo stesso confronto tipizzato.
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));
}
}I record lo implementano automaticamente
Un record C# genera automaticamente IEquatable<T>, Equals basato sul valore e GetHashCode. Quando serve solo l'uguaglianza basata sul valore, un record evita codice ripetitivo.
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);
}
}Quando implementarlo manualmente
Implementi IEquatable<T> manualmente quando servono regole di uguaglianza personalizzate, come nomi senza distinzione tra maiuscole e minuscole o l'esclusione di determinati campi, che un record non può esprimere direttamente.
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")));
}
}Provi Lei
Implementi IEquatable<T> per un piccolo tipo riferimento e faccia passare ogni percorso di uguaglianza attraverso il metodo tipizzato.
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)));
}
}Verifica rapida
Ricordi il vantaggio di IEquatable
Riepilogo
IEquatable<T> fornisce un'uguaglianza sicura rispetto al tipo.
- Fornisce
Equals(T other), evitando il boxing per le strutture e i cast per le classi. - Le raccolte lo preferiscono per ricerche corrette ed efficienti.
- Faccia passare
object.Equalse gli operatori attraverso il metodo tipizzato. - I record lo implementano automaticamente; lo implementi manualmente per regole personalizzate.
Domande Frequenti
La lezione «Implementazione di IEquatable» è gratuita?
Sì — il testo completo di «Implementazione di IEquatable» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso C# Academy, passa a CoddyKit PRO. Il corso C# Academy include 4 lezioni in totale.
Cosa imparerò in «Implementazione di IEquatable»?
Fornisca un'uguaglianza indipendente dal tipo con Equals. Eserciti C# Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.
Ho bisogno di esperienza per iniziare C# Academy?
Non è richiesta alcuna esperienza precedente. C# Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 1 di 4.
Quanto tempo richiede la lezione «Implementazione di IEquatable»?
La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.
Posso scrivere ed eseguire codice in questa lezione C# Academy?
Sì. Ogni lezione C# Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.
Tutte le lezioni di questo corso
- Implementazione di IEquatable
- Override di GetHashCode
- Implementazione di IComparable
- IComparer per l'ordinamento personalizzato