C# Language Sovraccarico di operatori di uguaglianza


Esempio

Sovraccaricare solo gli operatori di uguaglianza non è sufficiente. In diverse circostanze, è possibile chiamare tutti i seguenti:

  1. object.Equals e object.GetHashCode
  2. IEquatable<T>.Equals (facoltativo, consente di evitare la boxe)
  3. operator == e operator != (facoltativo, consente di utilizzare gli operatori)

Quando si Equals override di Equals , anche GetHashCode deve essere sostituito. Quando si implementa Equals , ci sono molti casi speciali: confronto con oggetti di un tipo diverso, confronto con il sé ecc.

Quando NON viene sovrascritto il metodo Equals e l'operatore == comportano diversamente per le classi e le strutture. Per le classi vengono confrontati solo i riferimenti e per i valori delle strutture le proprietà vengono confrontate tramite la riflessione, cosa può influire negativamente sulle prestazioni. == non può essere usato per confrontare le strutture a meno che non sia sovrascritto.

Generalmente l'operazione di uguaglianza deve rispettare le seguenti regole:

  • Non deve generare eccezioni .
  • Reflexivity: A sempre uguale a A (potrebbe non essere vero per i valori NULL in alcuni sistemi).
  • Transitvity: se A uguale a B , e B uguale a C , allora A uguale a C
  • Se A uguale a B , allora A e B hanno uguali codici hash.
  • Indipendenza dell'albero di successione: se B e C sono istanze di Class2 ereditate da Class1 : Class1.Equals(A,B) deve sempre restituire lo stesso valore della chiamata a 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);
    }
}