Égalité et hachage (valeur et référence)
Comprenez l’égalité par référence et l’égalité par valeur, surchargez correctement Equals/GetHashCode, implémentez IEquatable et utilisez des comparateurs personnalisés avec les ensembles et dictionnaires.
Égalité et hachage (valeur et référence) est une leçon C# Academy gratuite sur CoddyKit. Ceci est la leçon 3 sur 3. 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 3 leçons au total.
Notions de l’égalité
Objectif : faire fonctionner l’égalité comme vous l’attendez.
- Égalité par référence ou par valeur
- Contrat entre Equals et GetHashCode
- IEquatable<T> pour gagner en rapidité
- Comparateurs personnalisés lorsque vous ne pouvez pas modifier le type
Piège de l’égalité par référence
Les classes utilisent par défaut l’égalité par référence. Deux objets distincts contenant les mêmes données ne sont pas égaux, sauf si vous implémentez l’égalité par valeur.
using System;
using System.Collections.Generic;
public sealed class Point // no overrides
{
public int X;
public int Y;
public Point(int x, int y){ X = x; Y = y; }
}
public class Program
{
public static void Main(string[] args)
{
Point a = new Point(1, 2);
Point b = new Point(1, 2);
Console.WriteLine("a == b ? " + (a == b)); // reference equality: False
Console.WriteLine("a.Equals(b) ? " + a.Equals(b)); // False
HashSet<Point> set = new HashSet<Point>();
set.Add(a);
Console.WriteLine("Contains b? " + set.Contains(b)); // False (unexpected)
}
}
Égalité par valeur implémentée
Implémentez IEquatable<T>, surchargez Equals et GetHashCode. Le hachage doit correspondre à l’égalité : des objets égaux → le même hachage.
using System;
using System.Collections.Generic;
public sealed class ValuePoint : IEquatable<ValuePoint>
{
public int X;
public int Y;
public ValuePoint(int x, int y){ X = x; Y = y; }
public bool Equals(ValuePoint other)
{
if (ReferenceEquals(other, null)) return false;
if (ReferenceEquals(this, other)) return true;
return X == other.X && Y == other.Y;
}
public override bool Equals(object obj)
{
return Equals(obj as ValuePoint);
}
public override int GetHashCode()
{
// Simple, stable combination (avoid randomness)
unchecked
{
int hash = 17;
hash = hash * 31 + X.GetHashCode();
hash = hash * 31 + Y.GetHashCode();
return hash;
}
}
}
public class Program
{
public static void Main(string[] args)
{
ValuePoint a = new ValuePoint(1, 2);
ValuePoint b = new ValuePoint(1, 2);
Console.WriteLine("a.Equals(b)? " + a.Equals(b)); // True
HashSet<ValuePoint> set = new HashSet<ValuePoint>();
set.Add(a);
Console.WriteLine("Contains b? " + set.Contains(b)); // True (value semantics)
}
}
Comparateur personnalisé
Passez un comparateur d’égalité<T> personnalisé à HashSet/Dictionnaire lorsque vous ne pouvez pas modifier le type lui-même.
using System;
using System.Collections.Generic;
public sealed class Person // imagine from a library; cannot edit
{
public string Name;
public int BirthYear;
public Person(string name, int year){ Name = name; BirthYear = year; }
}
public sealed class PersonComparer : IEqualityComparer<Person>
{
public bool Equals(Person a, Person b)
{
if (ReferenceEquals(a, b)) return true;
if (ReferenceEquals(a, null) || ReferenceEquals(b, null)) return false;
return a.Name == b.Name && a.BirthYear == b.BirthYear;
}
public int GetHashCode(Person p)
{
if (ReferenceEquals(p, null)) return 0;
unchecked
{
int h = 23;
h = h * 31 + (p.Name == null ? 0 : p.Name.GetHashCode());
h = h * 31 + p.BirthYear.GetHashCode();
return h;
}
}
}
public class Program
{
public static void Main(string[] args)
{
Person p1 = new Person("Ada", 1815);
Person p2 = new Person("Ada", 1815);
HashSet<Person> set = new HashSet<Person>(new PersonComparer());
set.Add(p1);
Console.WriteLine("Contains p2? " + set.Contains(p2)); // True via comparer
}
}
Contrat et pièges
Règles :
- Si Equals(a,b) est vrai ⇒ GetHashCode(a) == GetHashCode(b)
- L’égalité doit être réflexive, symétrique et transitive
- Utilisez autant que possible des champs immuables pour le hachage
- N’utilisez pas de valeurs aléatoires dans GetHashCode
Remarque sur les structures et les classes
Les structures sont comparées champ par champ par défaut (sémantique de valeur). Les classes sont comparées par référence, sauf si vous implémentez l’égalité par valeur.
using System;
public struct PointS // struct: value type
{
public int X;
public int Y;
public PointS(int x, int y){ X = x; Y = y; }
}
public class Program
{
public static void Main(string[] args)
{
PointS a = new PointS(1, 2);
PointS b = new PointS(1, 2);
Console.WriteLine("Struct equality: " + a.Equals(b)); // True by default (field-wise)
}
}
Contrat d’égalité pour les collections
Récapitulatif
Récapitulatif : les classes ont besoin de Equals/GetHashCode (et souvent de IEquatable<T>) pour une sémantique de valeur ; utilisez des comparateurs personnalisés lorsque les types ne sont pas modifiables.
Questions Fréquemment Posées
La leçon « Égalité et hachage (valeur et référence) » est-elle gratuite ?
Oui — le texte complet de « Égalité et hachage (valeur et référence) » 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 3 leçons au total.
Qu'est-ce que j'apprendrai dans « Égalité et hachage (valeur et référence) » ?
Comprenez l’égalité par référence et l’égalité par valeur, surchargez correctement Equals/GetHashCode, implémentez IEquatable et utilisez des comparateurs personnalisés avec les ensembles et dictionn… 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 3 sur 3.
Combien de temps prend la leçon « Égalité et hachage (valeur et référence) » ?
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
- HashSet , SortedSet , Queue et Stack
- ConcurrentDictionary et collections immuables
- Égalité et hachage (valeur et référence)