Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
C# 14 enthält die folgenden neuen Features. Sie können diese Features mit der neuesten Visual Studio 2022--Version oder dem .NET 10 SDK-ausprobieren:
- Erweiterungsmitglieder
- Null-bedingte Zuordnung
-
nameof
unterstützt ungebundene generische Typen -
Implizitere Konvertierungen für
Span<T>
undReadOnlySpan<T>
- Modifizierer für einfache Lambda-Parameter
-
field
Gesicherte Eigenschaften -
partial
Ereignisse und Konstrukteure - benutzerdefinierte Verbundzuordnungsoperatoren
C# 14 wird für .NET 10unterstützt. Weitere Informationen finden Sie unter C#-Sprachversionsverwaltung.
Sie können das neueste .NET 10 SDK von der .NET-Downloadseiteherunterladen. Sie können auch Visual Studio 2022-herunterladen, das das .NET 10 SDK enthält.
Neue Features werden der Seite "Neuigkeiten in C#" hinzugefügt, wenn sie in öffentlichen Vorschauversionen verfügbar sind. Der Arbeitssatzabschnitt der Roslyn-Featurestatusseite verfolgt, wenn anstehende Features in die Hauptzweige zusammengeführt werden. Dieser Artikel wurde zuletzt für .NET 10 Preview 1 aktualisiert.
Alle fehlerhaften Änderungen, die in C# 14 eingeführt wurden, finden Sie in unserem Artikel über fehlerhafte Änderungen.
Hinweis
Wir interessieren uns für Ihr Feedback zu diesen Features. Wenn Sie bei einem dieser neuen Features auf Probleme stoßen, erstellen Sie ein neues Problem im Repository dotnet/roslyn.
Erweiterungsmember
C# 14 fügt neue Syntax zum Definieren von Erweiterungsmitgliedern hinzu. Mit der neuen Syntax können Sie Erweiterungseigenschaften zusätzlich zu Erweiterungsmethoden deklarieren. Sie können auch Erweiterungsmitglieder deklarieren, die den Typ erweitern, anstatt einer Instanz des Typs. Mit anderen Worten, diese neuen Erweiterungsmitglieder können als statische Mitglieder des Typs auftreten, den Sie erweitern. Das folgende Codebeispiel zeigt ein Beispiel für die verschiedenen Arten von Erweiterungsmitgliedern, die Sie deklarieren können:
public static class Enumerable
{
// Extension block
extension<TSource>(IEnumerable<TSource> source) // extension members for IEnumerable<TSource>
{
// Extension property:
public bool IsEmpty => !source.Any();
// Extension indexer:
public TSource this[int index] => source.Skip(index).First();
// Extension method:
public IEnumerable<TSource> Where(Func<TSource, bool> predicate) { ... }
}
// extension block, with a receiver type only
extension<TSource>(IEnumerable<TSource>) // static extension members for IEnumerable<Source>
{
// static extension method:
public static IEnumerable<TSource> Combine(IEnumerable<TSource> first, IEnumerable<TSource> second) { ... }
// static extension property:
public static IEnumerable<TSource> Identity => Enumerable.Empty<TSource>();
}
}
Die Mitglieder im ersten Erweiterungsblock werden aufgerufen, als ob sie Instanzmitglieder von IEnumerable<TSource>
sind, z. B. sequence.IsEmpty
... Die Mitglieder im zweiten Erweiterungsblock werden aufgerufen, als wären sie statische Mitglieder von IEnumerable<TSource>
, z. B. IEnumerable<int>.Identity
.
Weitere Informationen erhalten Sie, indem Sie den Artikel zu Erweiterungsmitgliedern im Programmierhandbuch, den Sprachreferenzartikel zum extension
Schlüsselwort und die Featurespezifikation für das neue Erweiterungsmitgliedsfeature lesen.
Das schlüsselwort field
Das Token field
ermöglicht es Ihnen, einen Eigenschafts-Accessor Body zu schreiben, ohne ein explizites Backing-Feld zu deklarieren. Das Token field
wird durch ein compilersynthetisiertes Sicherungsfeld ersetzt.
Wenn Sie zum Beispiel sicherstellen wollten, dass eine string
-Eigenschaft nicht auf null
gesetzt werden kann, mussten Sie bisher ein Hintergrundfeld deklarieren und beide Accessoren implementieren:
private string _msg;
public string Message
{
get => _msg;
set => _msg = value ?? throw new ArgumentNullException(nameof(value));
}
Sie können Ihren Code jetzt wie folgt vereinfachen:
public string Message
{
get;
set => field = value ?? throw new ArgumentNullException(nameof(value));
}
Sie können einen Body für einen oder beide Accessoren für eine Eigenschaft mit Backing-Feld deklarieren.
Beim Lesen von Code in Typen, die auch ein Symbol mit dem Namen field
enthalten, kann es zu einem Bruch oder einer Verwirrung kommen. Sie können @field
oder this.field
verwenden, um zwischen dem Schlüsselwort field
und dem Bezeichner zu unterscheiden, oder Sie können das aktuelle field
-Symbol umbenennen, um eine bessere Unterscheidung zu ermöglichen.
Wenn Sie diese Funktion ausprobieren und ein Feedback haben, kommentieren Sie das Feature Issue im csharplang
Repository.
Das kontextbezogene Schlüsselwort field
ist in C# 13 als Vorschaufeature enthalten.
Implizite SPAN-Konvertierungen
C# 14 führt erstklassige Unterstützung für System.Span<T> und System.ReadOnlySpan<T> in der Sprache ein. Diese Unterstützung umfasst neue implizite Konvertierungen, die eine natürlichere Programmierung mit diesen Typen ermöglichen.
Span<T>
und ReadOnlySpan<T>
werden in C# und der Laufzeitumgebung in vielen wichtigen Bereichen verwendet. Ihre Einführung verbessert die Leistung, ohne die Sicherheit zu gefährden. C# 14 erkennt die Beziehung und unterstützt einige Konvertierungen zwischen ReadOnlySpan<T>
, Span<T>
und T[]
. Die SPAN-Typen können Erweiterungsmethodenempfänger sein, mit anderen Konvertierungen komponieren und bei generischen Typ-Inferenzszenarien helfen.
Die Liste der impliziten span-Konvertierungen finden Sie im Artikel Bauteile im Abschnitt Sprachreferenz. Weitere Einzelheiten erfahren Sie in der Funktionsbeschreibung für First class span types.
Ungebundene generische Typen und nameof
Ab C# 14 kann das Argument für nameof
ein ungebundener generischer Typ sein.
nameof(List<>)
ergibt beispielsweise List
. In früheren Versionen von C# können nur geschlossene generische Typen wie List<int>
verwendet werden, um den List
Namen zurückzugeben.
Einfache Lambda-Parameter mit Modifizierern
Sie können Parametermodifizierer wie scoped
, ref
, in
, out
oder ref readonly
zu Lambda-Ausdrucksparametern hinzufügen, ohne den Parametertyp anzugeben:
delegate bool TryParse<T>(string text, out T result);
// ...
TryParse<int> parse1 = (text, out result) => Int32.TryParse(text, out result);
Zuvor war das Hinzufügen von Modifizierern nur zulässig, wenn die Parameterdeklarationen die Typen für die Parameter enthielten. Für die vorangehende Deklaration sind Typen für alle Parameter erforderlich:
TryParse<int> parse2 = (string text, out int result) => Int32.TryParse(text, out result);
Für den params
Modifizierer ist weiterhin eine explizit eingegebene Parameterliste erforderlich.
Weitere Informationen zu diesen Änderungen finden Sie im Artikel zu Lambda-Ausdrücken in der C#-Sprachreferenz.
Weitere partielle Mitglieder
Sie können jetzt Instanzkonstruktoren und Ereignisse als Teilmitgliederdeklarieren.
Partielle Konstruktoren und partielle Ereignisse müssen genau eine definierende Erklärung und eine implementierende Erklärungenthalten.
Nur die Implementierungsdeklaration eines Teilkonstruktors kann einen Konstruktorinitialisierer enthalten: this()
oder base()
. Nur eine partielle Typdeklaration kann die primäre Konstruktorsyntax enthalten.
Die Implementierungsdeklaration eines Teilereignisses muss die Accessoren add
und remove
enthalten. Die definierende Deklaration deklariert ein feldähnliches Ereignis.
Benutzerdefinierte zusammengesetzte Zuweisung
Weitere Informationen finden Sie in der Featurespezifikation für benutzerdefinierte Verbundzuweisungen.
Null-bedingte Zuweisung
Die Operatoren ?.
für den zugriff auf Null-bedingte Member und ?[]
können jetzt auf der linken Seite einer Zuordnung oder einer zusammengesetzten Zuordnung verwendet werden.
Vor C# 14 mussten Sie eine Variable auf Null prüfen, bevor Sie sie einer Eigenschaft zuweisen:
if (customer is not null)
{
customer.Order = GetCurrentOrder();
}
Sie können den vorherigen Code mithilfe des ?.
Operators vereinfachen:
customer?.Order = GetCurrentOrder();
Die rechte Seite des =
Operators wird nur ausgewertet, wenn die linke Seite nicht NULL ist. Wenn customer
null ist, ruft der Code nicht auf GetCurrentOrder
.
Zusätzlich zur Zuweisung können Sie Operatoren für den Zugriff auf Elemente mit Null-bedingten Membern mit zusammengesetzten Zuordnungsoperatoren (+=
, -=
und anderen) verwenden. Inkrementieren und Dekrementieren, ++
und --
, sind jedoch nicht zulässig.
Weitere Informationen finden Sie im Sprachreferenzartikel über den bedingten Memberzugriff und die Featurespezifikation für null-bedingte Zuweisung.