0Pricing
C# Academy · Lektion

Vergleichsoperatoren überladen

Implementieren Sie ==, != und Sortierungsoperatoren.

Vergleichsoperatoren überladen ist eine kostenlose C# Academy-Lektion auf CoddyKit. Dies ist Lektion 2 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des C# Academy-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der C# Academy-Kurs umfasst insgesamt 4 Lektionen.

Vergleichsoperatoren und Gleichheit

Wenn Sie == überladen, müssen Sie auch != überladen. Außerdem sollten Sie Equals und GetHashCode überschreiben, damit alle Formen der Gleichheitsprüfung konsistent bleiben. C# erzwingt die Paarung der Operatoren bereits zur Kompilierzeit.

== und != überladen

Der Compiler verlangt, dass == und != gemeinsam definiert werden. Beide geben einen bool-Wert zurück, der angibt, ob die Operanden als gleich betrachtet werden.

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));
    }
}

Equals immer ebenfalls überschreiben

Operatoren werden zur Kompilierzeit anhand des statischen Typs aufgelöst, aber Equals ist virtuell und wird von Collections verwendet. Überschreiben Sie Equals, damit Dictionaries und List.Contains dasselbe Ergebnis wie Ihr == liefern.

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 muss zur Gleichheit passen

Wenn zwei Werte gleich sind, müssen sie denselben Hashcode zurückgeben. Andernfalls verhalten sich hashbasierte Collections wie Dictionary und HashSet fehlerhaft.

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)));
    }
}

Sortierungsoperatoren < und >

Sie können auch relationale Operatoren überladen. Wie bei der Gleichheit müssen < und > gemeinsam definiert werden, ebenso <= und >=.

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));
    }
}

Gleichheit bei Referenztypen

Bei Klassen bedeutet Wertgleichheit, dass Felder statt Referenzen verglichen werden. Behandeln Sie null sorgfältig, damit innerhalb des Operators keine Ausnahme ausgelöst wird.

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"));
    }
}

Konsistenz über alle Formen hinweg

Alle Wege der Gleichheitsprüfung sollten dasselbe Ergebnis liefern: ==, Equals und der Hashcode. Implementieren Sie == anhand von Equals (oder umgekehrt), sodass es nur eine maßgebliche Vergleichslogik gibt.

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)));
    }
}

Operatoren und Equals in Collections

Bei der Suche in einer Liste wird Equals und nicht == verwendet, da sie mit object-Referenzen arbeitet. Wenn Sie nur == überladen und Equals vergessen, verwendet die Suche die Referenzidentität und kann fehlschlagen.

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")));
    }
}

Compilerwarnungen korrekt unterdrücken

Das Überschreiben von Equals und GetHashCode zusammen mit Operatoren ist nicht nur eine Frage des guten Stils. Der Compiler warnt, wenn Sie == überladen, ohne Equals zu überschreiben. Beides zu implementieren beseitigt die Warnung und verhindert Fehler.

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));
    }
}

Alles zusammenführen

Ein gut implementierter gleichheitsfähiger Typ definiert == und !=, überschreibt Equals und GetHashCode und führt sie alle über einen einzigen Vergleich zusammen. Das ist der Maßstab für wertähnliche Typen.

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)]);
    }
}

Probieren Sie es selbst aus

Implementieren Sie eine vollständig konsistente, gleichheitsfähige Struktur und überprüfen Sie, dass sie gleichzeitig als Schlüssel für ein Dictionary und mit dem Operator == funktioniert.

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)]);
    }
}

Kurztest

Rufen Sie sich die Regeln für das Überladen von Gleichheitsoperatoren in Erinnerung.

Zusammenfassung

Das Überladen von Vergleichsoperatoren erfordert Konsistenz.

  • == und != müssen gemeinsam definiert werden, ebenso </>.
  • Überschreiben Sie Equals und GetHashCode passend zu ==.
  • Gleiche Werte müssen denselben Hashcode haben.
  • Führen Sie alle Gleichheitsprüfungen über eine einzige Vergleichsmethode, damit die Implementierungen nicht auseinanderlaufen.

Häufig gestellte Fragen

Ist die Lektion „Vergleichsoperatoren überladen“ kostenlos?

Ja — der vollständige Text von „Vergleichsoperatoren überladen“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des C# Academy-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der C# Academy-Kurs umfasst insgesamt 4 Lektionen.

Was lerne ich in „Vergleichsoperatoren überladen“?

Implementieren Sie ==, != und Sortierungsoperatoren. Du übst C# Academy mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.

Brauche ich Erfahrung, um C# Academy zu starten?

Keine Vorkenntnisse erforderlich. C# Academy auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 2 von 4.

Wie lange dauert die Lektion „Vergleichsoperatoren überladen“?

Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.

Kann ich in dieser C# Academy-Lektion Code schreiben und ausführen?

Ja. Jede C# Academy-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.

Alle Lektionen in diesem Kurs

  1. Arithmetische Operatoren überladen
  2. Vergleichsoperatoren überladen
  3. Benutzerdefinierte Konvertierungen
  4. Best Practices für Operatorüberladung
← Zurück zu C# Academy