Surcharge des opérateurs de comparaison
Implémentez les opérateurs ==, != et les opérateurs d’ordre.
Surcharge des opérateurs de comparaison est une leçon C# Academy gratuite sur CoddyKit. Ceci est la leçon 2 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage C# Academy, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours C# Academy comprend 4 leçons au total.
Opérateurs de comparaison et égalité
Lorsque vous surchargez ==, vous devez également surcharger != et vous devriez remplacer Equals et GetHashCode afin de maintenir la cohérence entre toutes les formes d’égalité. C# impose l’association de ces opérateurs au moment de la compilation.
Surcharger == et !=
Le compilateur exige que == et != soient définis ensemble. Chacun renvoie un bool indiquant si les opérandes sont considérés comme égaux.
using System;
public struct Point
{
public int X, Y;
public Point(int x, int y) { X = x; Y = y; }
public static bool operator ==(Point a, Point b) => a.X == b.X && a.Y == b.Y;
public static bool operator !=(Point a, Point b) => !(a == b);
public override bool Equals(object obj) => obj is Point p && this == p;
public override int GetHashCode() => HashCode.Combine(X, Y);
}
public class Program
{
public static void Main()
{
Console.WriteLine(new Point(1, 2) == new Point(1, 2));
Console.WriteLine(new Point(1, 2) != new Point(3, 4));
}
}Remplacez toujours Equals également
Les opérateurs sont résolus au moment de la compilation selon le type statique, tandis que Equals est virtuel et utilisé par les collections. Remplacez Equals afin que les dictionnaires et List.Contains soient cohérents avec votre opérateur ==.
using System;
public struct Point
{
public int X, Y;
public Point(int x, int y) { X = x; Y = y; }
public static bool operator ==(Point a, Point b) => a.X == b.X && a.Y == b.Y;
public static bool operator !=(Point a, Point b) => !(a == b);
public override bool Equals(object obj) => obj is Point p && this == p;
public override int GetHashCode() => HashCode.Combine(X, Y);
}
public class Program
{
public static void Main()
{
object a = new Point(1, 2);
object b = new Point(1, 2);
Console.WriteLine(a.Equals(b));
}
}GetHashCode doit correspondre à l’égalité
Si deux valeurs sont égales, elles doivent renvoyer le même code de hachage. Sinon, les collections fondées sur le hachage, comme Dictionary et HashSet, fonctionneront incorrectement.
using System;
using System.Collections.Generic;
public struct Point
{
public int X, Y;
public Point(int x, int y) { X = x; Y = y; }
public static bool operator ==(Point a, Point b) => a.X == b.X && a.Y == b.Y;
public static bool operator !=(Point a, Point b) => !(a == b);
public override bool Equals(object obj) => obj is Point p && this == p;
public override int GetHashCode() => HashCode.Combine(X, Y);
}
public class Program
{
public static void Main()
{
var set = new HashSet<Point> { new Point(1, 2) };
Console.WriteLine(set.Contains(new Point(1, 2)));
}
}Opérateurs d’ordre < et >
Vous pouvez également surcharger les opérateurs relationnels. Comme pour l’égalité, < et > doivent être définis ensemble, tout comme <= et >=.
using System;
public struct Weight
{
public int Grams;
public Weight(int g) { Grams = g; }
public static bool operator <(Weight a, Weight b) => a.Grams < b.Grams;
public static bool operator >(Weight a, Weight b) => a.Grams > b.Grams;
public override string ToString() => Grams + "g";
}
public class Program
{
public static void Main()
{
Console.WriteLine(new Weight(100) < new Weight(200));
Console.WriteLine(new Weight(300) > new Weight(200));
}
}Égalité pour les types référence
Pour les classes, l’égalité des valeurs signifie comparer les champs plutôt que les références. Gérez null avec précaution pour éviter de lever une exception dans l’opérateur.
using System;
public class Person
{
public string Name;
public Person(string name) { Name = name; }
public static bool operator ==(Person a, Person b)
{
if (ReferenceEquals(a, b)) return true;
if (a is null || b is null) return false;
return a.Name == b.Name;
}
public static bool operator !=(Person a, Person b) => !(a == b);
public override bool Equals(object obj) => this == (obj as Person);
public override int GetHashCode() => Name?.GetHashCode() ?? 0;
}
public class Program
{
public static void Main()
{
Console.WriteLine(new Person("Ann") == new Person("Ann"));
}
}Cohérence entre toutes les formes
Toutes les voies de comparaison d’égalité doivent produire le même résultat : ==, Equals et le code de hachage. Implémentez == en vous appuyant sur Equals (ou l’inverse) afin de disposer d’une seule source de vérité.
using System;
public struct 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 static bool operator ==(Id a, Id b) => a.Equals(b);
public static bool operator !=(Id a, Id b) => !a.Equals(b);
}
public class Program
{
public static void Main()
{
Console.WriteLine(new Id(7) == new Id(7));
Console.WriteLine(new Id(7).Equals(new Id(8)));
}
}Opérateurs et Equals dans les collections
La recherche dans une liste utilise Equals, et non ==, car elle fonctionne avec des références de type object. Si vous surchargez uniquement == et oubliez Equals, les recherches utiliseront l’identité des références et pourront échouer.
using System;
using System.Collections.Generic;
public struct Tag
{
public string Name;
public Tag(string name) { Name = name; }
public override bool Equals(object obj) => obj is Tag t && t.Name == Name;
public override int GetHashCode() => Name?.GetHashCode() ?? 0;
public static bool operator ==(Tag a, Tag b) => a.Equals(b);
public static bool operator !=(Tag a, Tag b) => !a.Equals(b);
}
public class Program
{
public static void Main()
{
var list = new List<Tag> { new Tag("red"), new Tag("blue") };
Console.WriteLine(list.Contains(new Tag("blue")));
}
}Supprimer correctement les avertissements du compilateur
Remplacer Equals et GetHashCode en même temps que les opérateurs n’est pas qu’une question de bonnes pratiques ; le compilateur vous avertit si vous surchargez == sans remplacer Equals. Faire les deux supprime l’avertissement et évite les bogues.
using System;
public struct Cell
{
public int Row, Col;
public Cell(int r, int c) { Row = r; Col = c; }
public override bool Equals(object obj) => obj is Cell c && c.Row == Row && c.Col == Col;
public override int GetHashCode() => HashCode.Combine(Row, Col);
public static bool operator ==(Cell a, Cell b) => a.Equals(b);
public static bool operator !=(Cell a, Cell b) => !a.Equals(b);
}
public class Program
{
public static void Main()
{
Console.WriteLine(new Cell(0, 0) == new Cell(0, 0));
}
}Tout mettre en place
Un type comparable correctement conçu définit == et !=, remplace Equals et GetHashCode, puis fait passer toutes ces opérations par une même comparaison. C’est la référence pour les types assimilables à des valeurs.
using System;
using System.Collections.Generic;
public struct Color
{
public int R, G, B;
public Color(int r, int g, int b) { R = r; G = g; B = b; }
public override bool Equals(object obj) => obj is Color c && c.R == R && c.G == G && c.B == B;
public override int GetHashCode() => HashCode.Combine(R, G, B);
public static bool operator ==(Color a, Color b) => a.Equals(b);
public static bool operator !=(Color a, Color b) => !a.Equals(b);
}
public class Program
{
public static void Main()
{
var dict = new Dictionary<Color, string> { [new Color(255, 0, 0)] = "red" };
Console.WriteLine(dict[new Color(255, 0, 0)]);
}
}Essayez par vous-même
Implémentez une structure comparable entièrement cohérente et vérifiez qu’elle fonctionne à la fois comme clé de dictionnaire et avec l’opérateur ==.
using System;
using System.Collections.Generic;
public struct GridPos
{
public int Row, Col;
public GridPos(int r, int c) { Row = r; Col = c; }
public override bool Equals(object obj) => obj is GridPos p && p.Row == Row && p.Col == Col;
public override int GetHashCode() => HashCode.Combine(Row, Col);
public static bool operator ==(GridPos a, GridPos b) => a.Equals(b);
public static bool operator !=(GridPos a, GridPos b) => !a.Equals(b);
}
public class Program
{
public static void Main()
{
var grid = new Dictionary<GridPos, string> { [new GridPos(1, 1)] = "player" };
Console.WriteLine(new GridPos(1, 1) == new GridPos(1, 1));
Console.WriteLine(grid[new GridPos(1, 1)]);
}
}Vérification rapide
Rappelez-vous les règles de surcharge de l’égalité.
Récapitulatif
La surcharge des opérateurs de comparaison exige de la cohérence.
==et!=doivent être définis ensemble, tout comme</>.- Remplacez
EqualsetGetHashCodeafin de les aligner sur==. - Les valeurs égales doivent partager le même code de hachage.
- Faites passer toutes les comparaisons d’égalité par une seule méthode de comparaison afin d’éviter les divergences.
Questions Fréquemment Posées
La leçon « Surcharge des opérateurs de comparaison » est-elle gratuite ?
Oui — le texte complet de « Surcharge des opérateurs de comparaison » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours C# Academy, passe à CoddyKit PRO. Le cours C# Academy comprend 4 leçons au total.
Qu'est-ce que j'apprendrai dans « Surcharge des opérateurs de comparaison » ?
Implémentez les opérateurs ==, != et les opérateurs d’ordre. Tu pratiques C# Academy avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.
Dois-je avoir de l'expérience pour commencer C# Academy ?
Aucune expérience préalable n'est requise. C# Academy sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 2 sur 4.
Combien de temps prend la leçon « Surcharge des opérateurs de comparaison » ?
La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.
Peux-tu écrire et exécuter du code dans cette leçon C# Academy ?
Oui. Chaque leçon C# Academy inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.
Toutes les leçons de ce cours
- Surcharge des opérateurs arithmétiques
- Surcharge des opérateurs de comparaison
- Conversions définies par l’utilisateur
- Bonnes pratiques pour la surcharge des opérateurs