C# Records einfach erklärt: Weniger Boilerplate-Code schreiben
Records in C# ersetten Boilerplate-Code: Wertgleichheit, Unveränderlichkeit und kompakte Syntax – einfach erklärt für alle, die C# lernen.
By Marcel Schmidtpeter 21 Sept 2026
Stell dir vor, du sitzt in deiner Ausbildung an einer kleinen Verwaltungssoftware. Für jeden Datentyp - Person, Adresse, Bestellung - brauchst du Properties, einen Konstruktor, `Equals`, `GetHashCode` und `ToString`. Bei drei Properties schreibst du schnell 40 Zeilen Code, von denen keine einzige echte Fachlogik enthält. Genau für diesen Fall gibt es C# Records - und die ersparen dir genau diesen Boilerplate-Code (Code, den du immer wieder von Hand schreiben müsstest, ohne dass er neue Logik enthält).
Was sind C# Records?
Ein Record ist ein Referenztyp in C#, bei dem der Compiler Gleichheitsvergleich, Ausgabe und Kopierlogik automatisch generiert. Eingeführt wurde er mit C# 9 und .NET 5 - du brauchst also ein halbwegs aktuelles Projekt. Die offizielle Dokumentation findest du auf Microsoft Learn.
So sieht die Klassik aus, die du vielleicht schon kennst:
public class Person
{
public string Vorname { get; init; }
public string Nachname { get; init; }
public int Alter { get; init; }
public Person(string vorname, string nachname, int alter)
{
Vorname = vorname;
Nachname = nachname;
Alter = alter;
}
public override bool Equals(object? obj) { /* ... */ }
public override int GetHashCode() { /* ... */ }
public override string ToString() { /* ... */ }
}Und so sieht derselbe Typ als Record aus:
public record Person(string Vorname, string Nachname, int Alter);Eine Zeile. Der Compiler generiert daraus den Konstruktor, die Properties, `Equals`, `GetHashCode`, `ToString` sowie die Operatoren `==` und `!=`.
Merke: Ein Record ist eine Abkürzung für eine datenorientierte Klasse - du schreibst eine Zeile, der Compiler erzeugt Dutzende.
Record vs. Klasse: Wo liegt der Unterschied?
Der wichtigste Unterschied liegt im Gleichheitsvergleich: Records vergleichen Werte, Klassen vergleichen Referenzen. Das klingt abstrakt, ist aber im Alltag extrem praktisch.
Eigenschaft | class | record |
`==` vergleicht | Referenz (Speicheradresse) | Werte der Properties |
`ToString()` | `"MyApp.Person"` | formatierte Werte |
Boilerplate-Aufwand | hoch | minimal |
Typisch für | Verhalten, Identität | reine Daten (DTOs) |
Wann nutzt du was? Nimm eine Klasse, wenn es auf die Identität ankommt - etwa bei einem `Kundenkonto`, das durch eine ID eindeutig ist. Nimm einen Record, wenn es auf die Werte ankommt - etwa bei einem `Adresse`-Datensatz. Wenn du die OOP-Grundlagen auffrischen willst, hilft dir unser Artikel zu den OOP-Prinzipien in C#.
Wertgleichheit: Warum zwei Records "gleich" sind
Bei Records bedeutet Gleichheit: Alle Properties haben dieselben Werte. Ob dahinter zwei verschiedene Objekte im Speicher liegen, spielt keine Rolle.
var person1 = new Person("Anna", "Schmidt", 25);
var person2 = new Person("Anna", "Schmidt", 25);
Console.WriteLine(person1 == person2); // True
Console.WriteLine(person1.Equals(person2)); // True
Console.WriteLine(ReferenceEquals(person1, person2)); // False
Console.WriteLine(person1);
// Ausgabe: Person { Vorname = Anna, Nachname = Schmidt, Alter = 25 }Warum ist das nützlich? Weil du in Tests oder beim Vergleichen von Datensätzen nicht selbst `Equals` und `GetHashCode` implementieren musst. Wie aufwendig das von Hand wäre, zeigen wir im Artikel zu ToString, Equals und GetHashCode.
Merke: Zwei Record-Instanzen mit identischen Werten gelten als gleich - unabhängig davon, wo sie im Speicher liegen.
Wie änderst du Daten ohne Mutation? Der with-Ausdruck
Record-Properties sind standardmäßig init-only - sie lassen sich nur bei der Objekterstellung setzen. Zum Ändern nutzt du den with-Ausdruck: Er erstellt eine Kopie mit geänderten Werten, das Original bleibt unverändert. Details dazu liefert die Doku zum with-Ausdruck.
var anna = new Person("Anna", "Schmidt", 25);
// Falsch: Properties sind init-only
anna.Alter = 26; // Compilerfehler CS8852
// Richtig: Kopie mit neuem Wert erstellen
var annaGeburtstag = anna with { Alter = 26 };
Console.WriteLine(anna.Alter); // 25
Console.WriteLine(annaGeburtstag.Alter); // 26Das Konzept dahinter heißt Unveränderlichkeit (Immutability): Einmal erstellte Objekte ändern sich nicht mehr. Warum ist das gut? Weil unveränderliche Objekte vor bösen Überraschungen schützen - niemand kann "heimlich" ein Feld ändern, während andere Code-Teile dasselbe Objekt benutzen. Das macht Code besonders bei mehreren Threads sicherer, ein Thema, das wir in C# async und await vertiefen.
Records im Alltag: Ein Praxisbeispiel
Hier ein vollständiges, lauffähiges Beispiel: ein Warenkorb mit Artikeln, gefiltert und mit Rabatt - kombiniert mit LINQ.
using System;
using System.Collections.Generic;
using System.Linq;
public record Artikel(string Name, decimal Preis, string Kategorie);
class Program
{
static void Main()
{
var warenkorb = new List<Artikel>
{
new("Tastatur", 49.99m, "Hardware"),
new("Maus", 19.99m, "Hardware"),
new("C# Buch", 39.90m, "Buecher")
};
// Alle Hardware-Artikel mit 10% Rabatt
var rabattArtikel = warenkorb
.Where(a => a.Kategorie == "Hardware")
.Select(a => a with { Preis = a.Preis * 0.9m });
foreach (var artikel in rabattArtikel)
{
Console.WriteLine(artikel);
}
}
}Die Ausgabe:
Artikel { Name = Tastatur, Preis = 44,991, Kategorie = Hardware }
Artikel { Name = Maus, Preis = 17,991, Kategorie = Hardware }Die "krummen" Preise sind korrekt gerechnet: 49,99 × 0,9 ergibt mit `decimal` exakt 44,991 - und das Komma statt des Punktes kommt von den deutschen Kultur-Einstellungen deines Systems.
Beachte außerdem: `warenkorb` selbst bleibt unverändert - der `with`-Ausdruck erzeugt neue Artikel-Instanzen. Die Liste `rabattArtikel` enthält andere Objekte als `warenkorb`, auch wenn die Namen gleich sind. Genau das ist der Vorteil: Du siehst sofort, welche Daten neu entstehen und welche bestehen bleiben.
Häufige Fehler bei C# Records
Fehler 1: Properties direkt ändern wollen. Record-Properties sind init-only. `anna.Alter = 26;` führt zum Compilerfehler. Nutze stattdessen `anna with { Alter = 26 }`.
Fehler 2: Referenzgleichheit erwarten. Wer von Klassen kommt, tippt manchmal `ReferenceEquals(a, b)` und wundert sich über `False`, obwohl die Werte identisch sind. Records vergleichen Werte - das ist kein Bug, sondern das Kernfeature.
Fehler 3: Veränderliche Daten einbauen. Enthält dein Record eine normale `List<T>`, kann jeder per `Add()` den Inhalt ändern - die Liste selbst ist ja veränderlich, auch wenn die Property init-only ist. Damit verschiebt sich der Hashwert, und zwei Records, die eben noch gleich waren, sind es plötzlich nicht mehr. In einem `Dictionary` oder `HashSet` findest du den Record dann nicht wieder. Halte Records konsequent unveränderlich, etwa mit `IReadOnlyList<T>` als Property-Typ.
So übst du am besten
Nimm eine Klasse aus einem deiner alten Projekte - idealerweise ein reines Datenobjekt wie `Kunde` oder `Artikel` - und baue sie in einen Record um. Prüfe danach drei Dinge: Funktioniert `==` wie erwartet? Was gibt `Console.WriteLine` aus? Lässt sich ein Wert per `with` ändern? Das Ganze dauert 15 Minuten und festigt das Konzept besser als jedes Lesen. Falls du bei Prüfungen sowieso gern auf Papier zurückgreifst: Auch Records eignen sich gut zum handschriftlichen Üben von Code.
FAQ: Häufige Fragen zu C# Records
Seit welcher C#-Version gibt es Records?
Seit C# 9 mit .NET 5 (2020). Record structs kamen mit C# 10 hinzu - das sind Records als Werttyp auf dem Stack.
Kann ein Record Methoden haben?
Ja. Ein Record ist syntaktisch eine Klasse - Methoden, Felder und alles andere sind erlaubt. Für viel Logik ist aber meist eine normale Klasse die bessere Wahl.
Sind Records immer unveränderlich?
Nein, aber standardmäßig ja. Du kannst mit `set` veränderliche Properties definieren - das untergräbt aber die Wertgleichheit und solltest du nur mit gutem Grund tun.
Record class oder record struct - was nehme ich?
Für den Anfang: `record` (also record class). Er ist ein Referenztyp und verhält sich in Collections und bei Übergaben vertrauter. Record structs sind eine Optimierung für kleine, häufig kopierte Daten.
Wann lieber eine normale Klasse?
Wenn das Objekt eine Identität über die Zeit braucht (ein Bankkonto, ein laufender Prozess) oder wenn es primär Verhalten statt Daten kapselt.
Fazit
C# Records gehören heute zum Standard-Repertoire moderner Projekte: eine Zeile statt 40, automatische Wertgleichheit, lesbare Ausgabe und sichere Änderungen per `with`. Für Datenklassen in Projekten, DTOs und Tests sind sie fast immer die bessere Wahl - für identitätsbehaftete Objekte mit viel Logik bleibt die Klasse. Probiere sie im nächsten kleinen Projekt einfach aus, der Einstieg kostet dich keine zehn Minuten.
Wenn du bei C# oder anderen IT-Themen auf dem Schlauch stehst - ob in der Ausbildung, im Studium oder beim Berufseinstieg - findest du bei study-it.education persönliche Nachhilfe, die genau dort ansetzt, wo du gerade stehst. Schau vorbei und melde dich für dein kostenloses Erstgespräch an.
Want 1:1 help with this topic?
Need someone to walk through this with you?
Instead of re-reading: 30 min with a senior dev.
Book a free first chat →
Records in C# ersetten Boilerplate-Code: Wertgleichheit, Unveränderlichkeit und kompakte Syntax – einfach erklärt für alle, die C# lernen.
marcel.schmidtpeter@study-it.education →More reading
C# JSON mit System.Text.Json lesen & schreiben – einfach erklärt
JSON-Daten in C# lesen und schreiben? Mit System.Text.Json gelingt dir Serialisierung & Deserialisierung – einfach erklärt für alle IT-Einsteiger.
C# xUnit Unit Test: So schreibst du deine ersten Unit Tests
Unit Tests mit xUnit machen deinen C#-Code belastbar. In diesem Tutorial lernst du [Fact], [Theory] und Assert kennen – für Einsteiger erklärt.
C# Datenbank verbinden: ADO.NET & Entity Framework einfach erklärt
So greifst du aus C# auf Datenbanken zu: mit ADO.NET für direktes SQL oder EF Core als modernem ORM – beide Wege mit Beispielen erklärt.