C# Language Surcharge des opérateurs d'égalité


Exemple

La surcharge des opérateurs d'égalité ne suffit pas. Dans des circonstances différentes, tous les éléments suivants peuvent être appelés:

  1. object.Equals et object.GetHashCode
  2. IEquatable<T>.Equals (facultatif, permet d'éviter la boxe)
  3. operator == et operator != (optionnel, permet d'utiliser des opérateurs)

Lors de la substitution de Equals , GetHashCode doit également être remplacé. Lorsque vous implémentez Equals , il existe de nombreux cas particuliers: comparer des objets d'un type différent, en les comparant à soi-même, etc.

Lorsque NOT surchargé, la méthode Equals et l'opérateur == se comportent différemment pour les classes et les structures. Pour les classes, seules les références sont comparées, et pour les structures, les valeurs des propriétés sont comparées par réflexion, ce qui peut avoir un impact négatif sur les performances. == ne peut pas être utilisé pour comparer des structures à moins qu’elles ne soient surchargées.

En règle générale, l'opération d'égalité doit obéir aux règles suivantes:

  • Ne pas jeter d'exceptions .
  • Réflexivité: A toujours égal à A (peut ne pas être vrai pour les valeurs NULL dans certains systèmes).
  • Transitvity: si A est égal à B et B est égal à C , alors A est égal à C
  • Si A est égal à B , alors A et B ont des codes de hachage égaux.
  • Indépendance de l'arbre d'héritage: si B et C sont des instances de Class2 héritées de Class1 : Class1.Equals(A,B) doivent toujours renvoyer la même valeur que l'appel à Class2.Equals(A,B) .
class Student : IEquatable<Student>
{
    public string Name { get; set; } = "";

    public bool Equals(Student other)
    {
        if (ReferenceEquals(other, null)) return false;
        if (ReferenceEquals(other, this)) return true;
        return string.Equals(Name, other.Name);
    }

    public override bool Equals(object obj)
    {
        if (ReferenceEquals(null, obj)) return false;
        if (ReferenceEquals(this, obj)) return true;

        return Equals(obj as Student);
    }

    public override int GetHashCode()
    {
        return Name?.GetHashCode() ?? 0;
    }

    public static bool operator ==(Student left, Student right)
    {
        return Equals(left, right);
    }

    public static bool operator !=(Student left, Student right)
    {
        return !Equals(left, right);
    }
}