Das neue Feldschlüsselwort in C# 14
[[academy-video-youtube({"vid": "_Z551_SKHA4", "start_time": "0", "title": "Das neue field Schlüsselwort in C# 14", "creator": "Tim Corey", "length": "10m 35s"})]]
Autopropetys in C# sind prägnant, aber sobald Sie Validierungs- oder Transformationslogik in einem Setter benötigen, müssen Sie sie vollständig aufgeben und eine vollständige Eigenschaft mit einem manuellen Hintergrundfeld schreiben. Der Sprung von einer Zeile auf sieben ist eine steile Steuer für das Hinzufügen einer einzigen Wächtersatzklausel. C# 14 führt das Schlüsselwort field ein, um diese Lücke zu schließen. Damit können Sie einen Getter oder Setter anpassen, während der Compiler das zugehörige Feld weiterhin für Sie verwaltet.
In seinem Video "Das neue field Schlüsselwort in C# 14" demonstriert Tim Corey das Problem, das dieses Feature löst, geht durch praktische Beispiele der Setter-Validierung und behandelt einen Namenskonflikt, den Sie vor dem Upgrade kennen sollten. Wir werden jeden Schritt im Detail durchgehen, sodass Sie field mit Zuversicht in Ihren eigenen Eigenschaften verwenden können.
Das Setup: Ein einfaches Personmodell
[0:12 - 1:07] Tim startet mit einer Konsolenanwendung, die auf .NET 10 und Visual Studio 2026 läuft. Die Demo konzentriert sich auf eine Person-Klasse mit einigen Eigenschaften:
public required string FirstName { get; set; }
public required string LastName { get; set; }
public int Age { get; set; }
public required string FirstName { get; set; }
public required string LastName { get; set; }
public int Age { get; set; }
Es gibt auch eine Demo-Eigenschaft, die von einem privaten Feld gestützt wird, was relevant wird, wenn der Namenskonflikt auftaucht. In Program.cs erstellt Tim eine Instanz mit FirstName = "Tim" und LastName = "Corey" und gibt dann den Nachnamen, das Alter und den Demo-Wert aus. Alles gibt wie erwartet aus: "Corey", 0 (der Standard-Ganzzahlwert) und "test".
Das Problem: Autopropetys akzeptieren fehlerhafte Daten
[1:23 - 2:49] Das Problem tritt auf, als Tim null nach der Konstruktion LastName zuweist:
p.LastName = null;
p.LastName = null;
Obwohl LastName als required markiert ist und als nicht-nullbarer String typisiert ist, wird die Zuweisung kompiliert. Der required-Modifikator erzwingt nur, dass ein Wert bei der Objektinitialisierung bereitgestellt wird; er verhindert nicht, dass jemand die Eigenschaft danach auf null setzt. Das Ergebnis ist ein leerer Nachname zur Laufzeit, ohne dass ein Fehler ausgelöst wird.
Das ist eine reale Lücke in der Datenintegrität. Das Typsystem warnt Sie mit einem nullable Reference Squiggle, aber das ist ein Kompilierungszeit-Hinweis, kein Laufzeitwächter. Wenn Ihre Anwendung davon abhängt, dass LastName immer einen gültigen String enthält, können automatische Eigenschaften diesen Vertrag allein nicht durchsetzen.
Die alte Lösung: Vollständige Eigenschaften mit manuellen Hintergrundfeldern
[2:58 - 4:19] Vor C# 14 war die Standardlösung, die Autopropety in eine vollständige Eigenschaft mit einem expliziten Hintergrundfeld zu konvertieren:
private string _lastName;
public required string LastName
{
get => _lastName;
set => _lastName = value ?? throw new ArgumentNullException(nameof(LastName));
}
private string _lastName;
public required string LastName
{
get => _lastName;
set => _lastName = value ?? throw new ArgumentNullException(nameof(LastName));
}
Tim führt dies aus und bestätigt, dass die Ausnahme korrekt ausgelöst wird: "Wert darf nicht null sein. Parametername: LastName." Der Ansatz funktioniert, erfordert jedoch die Deklaration eines privaten Felds, das Verkabeln von Getter und Setter und das Wiederholen des Eigenschaftsnnamens über mehrere Zeilen. Für eine einzelne Validierungsregel ist das viel Zeremonie.
Der Getter in diesem Fall tut nichts Besonderes; er gibt das Feld unverändert zurück. Dennoch müssen Sie ihn explizit schreiben, da die Syntax beide Hälften erfordert, sobald Sie den Autopropety-Bereich verlassen. Tim rahmt diese Geschwätzigkeit als Motivation für das neue Feature.
Die C# 14 Lösung: Das field-Schlüsselwort
[4:23 - 5:47] C# 14 führt einen Mittelweg ein. Anstatt ein privates zugehöriges Feld selbst zu deklarieren, verwenden Sie das kontextbezogene Schlüsselwort field innerhalb eines Getters oder Setters, um direkt auf das vom Compiler generierte zugehörige Feld zu verweisen:
public required string LastName
{
get;
set => field = value ?? throw new ArgumentNullException(nameof(LastName));
}
public required string LastName
{
get;
set => field = value ?? throw new ArgumentNullException(nameof(LastName));
}
Der Getter bleibt eine automatisch implementierte get;, für die kein Körper erforderlich ist. Der Setter verwendet field, um den ankommenden value nach der Validierung zuzuweisen. Der Compiler erstellt und verwaltet das Hintergrundfeld im Hintergrund, genau wie bei einem Standard-Autopropety.
Das Ausführen der Demo erzeugt den gleichen ArgumentNullException bei null Zuweisung. Das Verhalten ist identisch mit der manuell unterstützten Version, komprimiert von sieben Zeilen zu einem fokussierten Block, der nur anpasst, was angepasst werden muss. Sie behalten den Autopropety-Getter, fügen Logik nur zum Setter hinzu und überspringen die manuelle Felderklärung vollständig.
Dies bietet eine nützliche Zwischenstufe zwischen einer einfachen Autopropety (eine Zeile, keine Validierung) und einer vollständigen Eigenschaft (sieben oder mehr Zeilen, vollständige Kontrolle). Wenn Ihre Logik nur den Setter betrifft, zahlen Sie nicht mehr den syntaktischen Preis, den Getter auch umzuschreiben.
Alter mit einer Setter-Wache validieren
[6:16 - 7:39] Um zu zeigen, dass field nicht auf Nullprüfungen beschränkt ist, fügt Tim Bereichsvalidierung zur Age Eigenschaft hinzu:
public int Age
{
get;
set
{
if (value > 0 && value < 120)
field = value;
}
}
public int Age
{
get;
set
{
if (value > 0 && value < 120)
field = value;
}
}
Hier ignoriert der Setter leise Werte außerhalb eines vernünftigen Bereichs. Die Zuweisung von -5 lässt Age auf seinem Standardwert von null, weil die Bedingung fehlschlägt und field nie geschrieben wird. Tim weist darauf hin, dass Sie stattdessen eine Ausnahme auslösen könnten, aber der stille Ansatz zeigt, dass der Setter-Körper jede Logik enthalten kann, die Sie benötigen, während er sich weiterhin auf field für die Speicherung verlässt.
Das Muster gilt allgemein: Einengung numerischer Bereiche, Entfernen von Leerzeichen aus Zeichenketten, Normalisierung von Groß-/Kleinschreibung oder jede Transformation, die Sie jedes Mal anwenden möchten, wenn eine Eigenschaft gesetzt wird.
Namenskonflikte mit vorhandenen field Variablen
[7:39 - 9:43] Tim stellt einen absichtlichen Grenzfall vor. Die Demo-Klasse hat ein privates Mitglied, das buchstäblich field genannt wird:
private string field = "test";
private string field = "test";
Sobald C# 14 aktiv ist, behandelt der Compiler field innerhalb eines Eigenschaftszugriffs als das Schlüsselwort anstelle der Variablen. Das bedeutet, dass eine Eigenschaft, die sich auf field bezieht, stillschweigend aus dem verborgenen Speicher hinter der Eigenschaft liest (der leer ist) anstelle des Zeichenfolgenmitglieds, das "test" enthält. Die Ausgabe ändert sich in leer, ohne Kompilierfehler, nur eine Warnung.
Es gibt zwei Umgehungsmöglichkeiten. Das Voranstellen mit this.field zeigt dem Compiler, dass Sie das Klassenebenenmitglied meinen, nicht das Schlüsselwort. Alternativ funktioniert das @field-Escape auf die gleiche Weise:
// Both refer to the instance variable, not the keyword
string demo => this.field;
string demo => @field;
// Both refer to the instance variable, not the keyword
string demo => this.field;
string demo => @field;
Tim empfiehlt dringend, jede Variable, die field genannt wird, beim Upgrade auf C# 14 umzubenennen. Ein schnelles "Alle umbenennen" in Ihrer IDE beseitigt die Zweideutigkeit dauerhaft. Der Konflikt tritt nur innerhalb von Eigenschaftenzugriffen auf; Konstruktoren und Methoden lösen field wie erwartet auf den Variablennamen auf, da diese Kontexte keinen impliziten Speicherspeicher haben.
Zusammenfassung: Weniger Boilerplate, gleiche Kontrolle
[10:04 - 10:28] Das Schlüsselwort field füllt eine praktische Lücke im Alltag von C#-Code. Eigenschaften, die eine Schutzklausel oder Transformation benötigen, erfordern nicht mehr eine komplette Umschreibung mit manuellen Sicherungsfeldern. Sie passen nur den Accessor an, der Logik benötigt und lassen den anderen als Standard-Autoumsetzung.
Abschluss
[10:28 - 10:35] Zur Zusammenfassung: Das Schlüsselwort field von C# 14 gibt Ihnen direkten Zugriff auf das implizite Speicherspeicher innerhalb eines Eigenschaftszugriffs. Verwenden Sie es, um Setter-Validierungen, Getter-Transformationen oder beides hinzuzufügen, ohne die Autoproperty-Syntax für Teile aufzugeben, die keine Anpassung benötigen.
Bevor Sie ein Upgrade durchführen, suchen Sie in Ihrem Code nach Variablen namens field und benennen Sie sie um. Diese eine Vorsichtsmaßnahme vermeidet das einzige wirkliche Problem, das diese Funktion einführt. Darüber hinaus ist es eine klare Reduzierung von Boilerplate, die sich natürlich in die Strukturierung der Modelle der meisten Entwickler integriert.
Beispiel-Tipp: Wenn Sie nur den Setter validieren müssen, lassen Sie den Getter als einfachen get; ohne Körper. Der Compiler behandelt es als Autoproperty-Getter, und Sie vermeiden es, eine Durchlaufrückgabe-Anweisung zu schreiben, die nichts hinzufügt.
Sehen Sie das vollständige Video auf seinem YouTube Kanal und gewinnen Sie weitere Einblicke in C#-Sprachfunktionen.
