4 min Lesezeit 21. Sept. 2026

C# IComparable IComparer einfach erklärt: So sortierst du Objekte

IComparable und IComparer bestimmen, wie Objekte in C# sortiert werden – einfach erklärt für Azubis, Studenten und Berufseinsteiger.

Marcel Schmidtpeter Von Marcel Schmidtpeter 21. Sept. 2026
C# IComparable IComparer einfach erklärt: So sortierst du Objekte

Dein Programm läuft, die Liste mit 50 Kundenobjekten ist gefüllt - und dann wirft `List.Sort()` eine `InvalidOperationException` mit der Meldung „Failed to compare two elements in the array". Genau in diesem Moment stolperst du über das Thema dieses Artikels: C# kann Zahlen und Strings automatisch sortieren, aber bei deinen eigenen Objekten muss es erst lernen, *wonach* es sortieren soll. Die Schnittstellen IComparable und IComparer sind genau dafür da - egal, ob du gerade deine Ausbildung zum Fachinformatiker machst, im Studium sitzt oder im ersten Job auf legacy Code losgehst.

Was ist IComparable in C#?

IComparable ist eine Schnittstelle, mit der eine Klasse selbst festlegt, wie ihre Objekte verglichen werden - die sogenannte natürliche Sortierreihenfolge. Implementierst du `IComparable<T>`, sagst du C#: „So vergleiche ich mich mit einem anderen Objekt meines Typs."

Stell dir eine Schulklasse vor, die sich für ein Klassenfoto aufstellen soll. Bei `IComparable` wissen die Schüler selbst, wohin sie gehören - zum Beispiel alphabetisch nach Nachname. Niemand muss es ihnen sagen.

Die Schnittstelle besteht aus genau einer Methode: `CompareTo`. Sie gibt einen `int` zurück:

  • negativ, wenn das aktuelle Objekt *vor* dem anderen kommt

  • 0, wenn beide gleich sind

  • positiv, wenn das aktuelle Objekt *nach* dem anderen kommt

Merke: `CompareTo` gibt nicht „größer" oder „kleiner" als `bool` zurück, sondern einen `int`: negativ = vorher, 0 = gleich, positiv = nachher. Diese drei Zustände brauchst du für stabile Vergleiche.

Die offizielle Dokumentation findest du bei Microsoft Learn.

IComparable an einem Beispiel

Hier eine Klasse `Artikel`, die sich nach Preis sortiert:

csharp
public class Artikel : IComparable<Artikel>
{
  public string Name { get; set; }
  public decimal Preis { get; set; }

  public int CompareTo(Artikel? other)
  {
    if (other == null)
    {
      return 1; // null gilt als "kleiner" -> aktuelles Objekt kommt danach
    }
    return this.Preis.CompareTo(other.Preis);
  }
}

Der Trick: `decimal` und `string` implementieren `CompareTo` bereits selbst. Du kannst also delegieren, statt die Logik selbst zu schreiben. Das ist weniger fehleranfällig als ein handgeschriebenes `this.Preis - other.Preis` - das klingt clever, kann aber bei Rundungsproblemen danebengehen.

Jetzt funktioniert `Sort()` ohne Argumente:

csharp
List<Artikel> lager = new List<Artikel>
{
  new Artikel { Name = "Monitor", Preis = 199.99m },
  new Artikel { Name = "Maus", Preis = 24.50m },
  new Artikel { Name = "Tastatur", Preis = 79.90m }
};

lager.Sort(); // sortiert automatisch nach Preis

Was ist IComparer in C#?

IComparer ist eine Schnittstelle für eine *separate* Vergleichsklasse - damit kannst du mehrere Sortierkriterien für denselben Typ definieren. Zurück zur Klassenfoto-Analogie: `IComparer` ist der Lehrer, der sagt „heute sortiert ihr nach Größe" und morgen „heute nach Alter". Die Schüler selbst (also deine Objekte) bleiben unverändert.

Das löst ein echtes Problem:

Merke: `IComparable` erlaubt genau eine natürliche Reihenfolge pro Typ. Brauchst du mehrere Sortierkriterien - z. B. Artikel mal nach Preis, mal nach Name -, kommst du um `IComparer<T>` nicht herum.

Die Implementierung sieht so aus:

csharp
public class ArtikelNameComparer : IComparer<Artikel>
{
  public int Compare(Artikel? x, Artikel? y)
  {
    if (x == null && y == null)
    {
      return 0;
    }
    if (x == null)
    {
      return -1;
    }
    if (y == null)
    {
      return 1;
    }
    return string.Compare(x.Name, y.Name, StringComparison.Ordinal);
  }
}

Die Verwendung sieht so aus:

csharp
var nameComparer = new ArtikelNameComparer();
lager.Sort(nameComparer); // sortiert jetzt nach Name

Doku dazu: IComparer<T> auf Microsoft Learn.

IComparable oder IComparer - wann nutzt du was?

Die einfache Regel: `IComparable` gehört in die Klasse, wenn es ein offensichtliches, übergeordnetes Sortierkriterium gibt. `IComparer` (oder ein Lambda) nutzt du für alles andere.

Kriterium

IComparable<T>

IComparer<T>

Wo implementiert?

In der Klasse selbst

In einer separaten Klasse

Anzahl Kriterien

Genau eins pro Typ

Beliebig viele

Aufruf

`liste.Sort()`

`liste.Sort(comparer)`

Typischer Einsatz

„Natürliche" Reihenfolge (z. B. `Person` nach `Id`)

Wechselnde Sortierungen (Name, Preis, Datum)

Klasse ändern nötig?

Ja

Nein - funktioniert auch mit Fremdcode

Für schnelle Einmal-Sortierungen brauchst du übrigens keine eigene Comparer-Klasse. `Sort()` akzeptiert auch ein Lambda vom Typ `Comparison<T>` - wie das genau funktioniert, habe ich im Artikel zu C# Lambda Expressions erklärt:

csharp
lager.Sort((a, b) => string.Compare(a.Name, b.Name, StringComparison.Ordinal));

Noch ein Hinweis für Studenten und Prüfungskandidaten: Bei LINQ nutzt du stattdessen `OrderBy` - das braucht kein `IComparable` auf der Klasse, weil du das Kriterium direkt mitgibst. Mehr dazu im Beitrag zu LINQ filtern und transformieren. Wenn du auch Python lernst: Dort löst du dieselbe Aufgabe mit `__lt__`, siehe Python Objekte sortieren mit sorted().

3 häufige Fehler bei IComparable und IComparer

Fehler 1: Sortieren ohne Implementierung. Rufst du `Sort()` auf einer `List<T>` auf, deren Typ weder `IComparable` implementiert noch ein Vergleichskriterium mitbekommt, fliegt dir eine `InvalidOperationException` um die Ohren. C# kann nicht raten, ob `artikel1 < artikel2` nach Preis oder Name gemeint ist.

Fehler 2: Rückgabewert falsch herum. Wer `other.Preis.CompareTo(this.Preis)` schreibt, sortiert absteigend statt aufsteigend - der Code kompiliert trotzdem fehlerfrei. Merke: `this` links, `other` rechts ergibt aufsteigend. Willst du absteigend sortieren, tauschst du gezielt die Operanden oder drehst das Ergebnis mit `-` um.

Fehler 3: Null-Checks vergessen. Fehlt die `null`-Prüfung in `CompareTo`, knallt es spätestens, wenn die Liste ein `null`-Element enthält - mit einer `NullReferenceException` mitten im Sortiervorgang. Besonders tückisch: Der Fehler tritt nicht beim `Sort()`-Aufruf selbst auf, sondern tief im Framework. Wie du `null` generell sauber behandelst, steht im Artikel zu Nullable-Typen in C#.

Übungstipp: Baue deine eigene Sortierlogik

Nimm dir 20 Minuten und erstelle eine Klasse `Song` mit den Properties `Titel`, `Interpret` und `Dauer` (als `int` in Sekunden). Implementiere `IComparable<Song>` so, dass nach Dauer sortiert wird. Schreibe danach einen `SongTitelComparer`, der nach Titel sortiert. Teste beide mit `Sort()` und gib die Liste mit einer `foreach`-Schleife aus.

Warum das funktioniert? Weil du dabei beide Schnittstellen einmal komplett selbst geschrieben hast - genau das wird in Prüfungen (z. B. IHK-Abschlussprüfung Teil 1) und in Vorstellungsgesprächen abgefragt. Grundlagen zu Listen findest du im Überblick zu C# Collections, die Typ-Grundlagen zu `<T>` im Beitrag zu Generics.

FAQ: Häufige Fragen zu IComparable und IComparer

Was gibt CompareTo zurück?

Einen `int`: einen negativen Wert, wenn das aktuelle Objekt vor dem Vergleichsobjekt einsortiert wird, `0` bei Gleichheit und einen positiven Wert, wenn es danach kommt. Viele nutzen dafür einfach `-1`, `0` und `1`.

Funktioniert List.Sort() ohne IComparable?

Nein. Wenn der Typ `IComparable` nicht implementiert und kein Comparer übergeben wird, wirft `Sort()` eine `InvalidOperationException`. Zahlen, Strings und `DateTime` implementieren die Schnittstelle übrigens von Haus aus - bei eigenen Klassen musst du selbst liefern.

Wann IComparable und wann IComparer?

`IComparable` für die eine, natürliche Standard-Sortierung, die in die Klasse gehört. `IComparer` für zusätzliche oder wechselnde Sortierkriterien - besonders bei Klassen, die du nicht ändern kannst oder darfst.

Kann ich auch ohne eigene Comparer-Klasse sortieren?

Ja, mit einem Lambda: `liste.Sort((a, b) => ...)`. Für größere Projekte ist eine benannte Comparer-Klasse aber wartbarer und wiederverwendbar. Alternativ bietet sich LINQ mit `OrderBy` an.

Gibt es einen Unterschied zwischen IComparable und IComparable<T>?

Ja. Die generische Version `IComparable<T>` ist typsicher und sollte heute Standard sein. Das nicht-generische `IComparable` stammt aus der Zeit vor Generics und arbeitet mit `object`, erfordert also Casting.

Fazit

`IComparable` und `IComparer` ergänzen sich: Ersteres gibt deiner Klasse eine natürliche Sortierreihenfolge, letzteres liefert flexible Zusatzsortierungen von außen. Wenn du einmal verinnerlicht hast, dass `CompareTo` nur „negativ, null, positiv" zurückgibt, kannst du jede Objektliste in C# sortieren - vom Lagerbestand bis zur Kundenliste.

Wenn du bei C#, OOP oder der Prüfungsvorbereitung gerade festhängst: Bei study-it.education bekommst du persönliche IT-Nachhilfe - ob Azubi, Student oder Quereinsteiger. Schau vorbei, wir sortieren deine Wissenslücken schneller als jeder Comparer.


Erstgespräch · 0 € · 30 min

Brauchst du jemand, der das mit dir durchgeht?

Statt nochmal lesen: 30 min mit einem Senior-Dev.

Kostenloses Erstgespräch buchen →
Über den Autor
Marcel Schmidtpeter
Marcel Schmidtpeter

IComparable und IComparer bestimmen, wie Objekte in C# sortiert werden – einfach erklärt für Azubis, Studenten und Berufseinsteiger.

marcel.schmidtpeter@study-it.education →
Weiterlesen

Mehr Lesestoff