Neuerungen in C# 13
C# 13 enthält die folgenden neuen Features. Sie können diese Features mit der neuesten Visual Studio 2022--Version oder dem .NET 9 SDK-ausprobieren:
-
params
Collections - Neuer
lock
Typ und Semantik. - Neue Escape-Sequenz -
\e
. - Verbesserungen der natürlichen Typen von Methodengruppen
- Impliziter Indexerzugriff in Objektinitialisierern
- Ermöglichen von
ref
Gebietsschemata undunsafe
Kontexten in Iteratoren und asynchronen Methoden - Ermöglichen von
ref struct
Typen die Implementierung von Schnittstellen. - Zulassen von Verweisstrukturtypen als Argumente für Typparameter in Generika.
- Partielle Eigenschaften und Indexer sind jetzt in
partial
Typen zulässig. - Priorität der Überladungsauflösung bietet Bibliotheksautoren die Möglichkeit, eine Überladung als besser als andere zu kennzeichnen.
Ab Visual Studio 17.12 enthält C# 13 das field
Kontextwort als Vorschaufeature.
C# 13 wird für .NET 9unterstützt. Weitere Informationen finden Sie unter C#-Sprachversionsverwaltung.
Sie können das neueste .NET 9 SDK von der .NET-Downloadseiteherunterladen. Sie können auch Visual Studio 2022-herunterladen, das das .NET 9 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.
Alle fehlerhaften Änderungen, die in C# 13 eingeführt wurden, finden Sie in unserem Artikel über fehlerhafte Änderungen.
Anmerkung
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.
params
Collections
Der params
Modifizierer ist nicht auf Arraytypen beschränkt. Sie können jetzt params
mit jedem erkannten Sammlungstyp verwenden, einschließlich System.Span<T>, System.ReadOnlySpan<T>und Typen, die System.Collections.Generic.IEnumerable<T> implementieren und über eine Add
Methode verfügen. Neben konkreten Typen können auch die Schnittstellen System.Collections.Generic.IEnumerable<T>, System.Collections.Generic.IReadOnlyCollection<T>, System.Collections.Generic.IReadOnlyList<T>, System.Collections.Generic.ICollection<T>und System.Collections.Generic.IList<T> verwendet werden.
Wenn ein Schnittstellentyp verwendet wird, synthetisiert der Compiler den Speicher für die angegebenen Argumente. Erfahren Sie mehr in der Spezifikation der Funktion für params
Collections.
Methodendeklarationen können beispielsweise Spannen als params
Parameter deklarieren:
public void Concat<T>(params ReadOnlySpan<T> items)
{
for (int i = 0; i < items.Length; i++)
{
Console.Write(items[i]);
Console.Write(" ");
}
Console.WriteLine();
}
Neues Sperrobjekt
Die .NET 9-Laufzeit enthält einen neuen Typ für die Threadsynchronisierung, den System.Threading.Lock Typ. Dieser Typ bietet eine bessere Threadsynchronisierung über die API. Die Lock.EnterScope()-Methode betritt einen exklusiven Bereich. Die ref struct
zurückgegeben wird, unterstützt die Dispose()
Muster, um den exklusiven Bereich zu verlassen.
Die C#-lock
-Anweisung erkennt, ob das Ziel der Sperre ein Lock
-Objekt ist. Wenn ja, wird die aktualisierte API anstelle der herkömmlichen API mit System.Threading.Monitorverwendet. Der Compiler erkennt auch, ob Sie ein Lock
-Objekt in einen anderen Typ konvertieren und der auf Monitor
basierende Code generiert würde. Weitere Informationen finden Sie in der Featurespezifikation für das neue Sperrobjekt .
Diese Funktion bietet Ihnen die Möglichkeit, die Vorteile des neuen Bibliothekstyps zu nutzen, indem Sie den Typ des Objekts ändern, das Sie lock
. Kein anderer Code muss geändert werden.
Neue Escapesequenz
Sie können \e
als zeichenliterale Escapesequenz für dasESCAPE
Zeichen Unicode U+001B
verwenden. Zuvor haben Sie \u001b
oder \x1b
verwendet. Die Verwendung \x1b
wurde nicht empfohlen, da diese Zeichen Teil der Escapesequenz wurden, wenn die folgenden 1b
Zeichen gültige hexadezimale Ziffern waren.
Methodengruppe natürlicher Typ
Dieses Feature führt kleine Optimierungen bei der Überlastungsauflösung unter Verwendung von Methodengruppen durch. Eine Methodengruppe ist eine Methode und alle Überladungen mit demselben Namen. Das vorherige Verhalten bestand darin, dass der Compiler den vollständigen Satz von Methoden für eine Methodengruppe erstellte. Wenn ein natürlicher Typ benötigt wurde, wurde der natürliche Typ aus dem vollständigen Satz von Kandidatenmethoden bestimmt.
Das neue Verhalten besteht darin, die Menge der Kandidatenmethoden in jedem Bereich auszudünnen, indem diejenigen Kandidatenmethoden entfernt werden, die nicht anwendbar sind. Typischerweise handelt es sich bei den entfernten Methoden um generische Methoden mit der falschen Arität oder um nicht erfüllte Einschränkungen. Der Prozess wird nur dann mit dem nächsten äußeren Bereich fortgesetzt, wenn keine Kandidatenmethoden gefunden werden. Dieser Prozess folgt genauer dem allgemeinen Algorithmus für die Überladungsauflösung. Wenn alle Kandidatenmethoden, die in einem bestimmten Bereich gefunden wurden, nicht übereinstimmen, weist die Methodengruppe keinen natürlichen Typ auf.
Sie können die Details der Änderungen in der Vorschlagsspezifikationlesen.
Impliziter Indexzugriff
Der implizite Indexoperator "vom Ende her", ^
, ist jetzt in einem Objektinitialisierungsausdruck zulässig. Sie können z. B. jetzt ein Array in einem Objektinitialisierer initialisieren, wie im folgenden Code gezeigt:
public class TimerRemaining
{
public int[] buffer { get; set; } = new int[10];
}
var countdown = new TimerRemaining()
{
buffer =
{
[^1] = 0,
[^2] = 1,
[^3] = 2,
[^4] = 3,
[^5] = 4,
[^6] = 5,
[^7] = 6,
[^8] = 7,
[^9] = 8,
[^10] = 9
}
};
Die TimerRemaining
Klasse enthält ein buffer
Array, das auf eine Länge von 10 initialisiert wurde. Im vorherigen Beispiel werden diesem Array Werte zugewiesen, wobei der Indexoperator "from the end" (^
) verwendet wird, wodurch effektiv ein Array erstellt wird, das von 9 bis 0 nach unten zählt.
In Versionen vor C# 13 kann der ^
-Operator nicht in einem Objektinitialisierer verwendet werden. Sie müssen die Elemente von vorne indexieren.
ref
und unsafe
in Iteratoren und async
Methoden
Mit diesem Feature und den folgenden beiden Features können ref struct
Typen neue Konstrukte verwenden. Sie werden diese nicht verwenden, es sei denn, Sie schreiben Ihre eigenen ref struct
Typen. Wahrscheinlich sehen Sie einen indirekten Vorteil, da System.Span<T> und System.ReadOnlySpan<T> mehr Funktionalität erhalten.
Vor C# 13 konnten Iteratormethoden (Methoden, die yield return
verwenden) und async
Methoden weder lokale ref
Variablen deklarieren noch einen unsafe
Kontext haben.
In C# 13 können async
Methoden ref
lokale Variablen oder lokale Variablen eines ref struct
Typs deklarieren. Auf diese Variablen kann jedoch nicht über eine await
Grenze zugegriffen werden. Auf sie kann nicht über eine yield return
-Grenze zugegriffen werden.
Diese lockere Einschränkung ermöglicht dem Compiler die nachweisbare sichere Verwendung von ref
lokalen Variablen und ref struct
Typen an weiteren Stellen. Sie können Typen wie System.ReadOnlySpan<T> in diesen Methoden sicher verwenden. Der Compiler teilt Ihnen mit, ob Sie sicherheitsregeln verletzen.
Auf die gleiche Weise ermöglicht C# 13 unsafe
Kontexte in Iteratormethoden. Alle yield return
- und yield break
-Anweisungen müssen jedoch in sicheren Kontexten stehen.
allows ref struct
Vor C# 13 konnten ref struct
Typen nicht als Typargument für einen generischen Typ oder eine generische Methode deklariert werden. Jetzt können generische Typdeklarationen eine Antieinschränkung allows ref struct
hinzufügen. Diese Antieinschränkung deklariert, dass das typargument, das für diesen Typparameter bereitgestellt wird, ein ref struct
Typ sein kann. Der Compiler erzwingt Ref-Sicherheitsregeln für alle Instanzen dieses Typparameters.
Sie können z. B. einen generischen Typ wie den folgenden Code deklarieren:
public class C<T> where T : allows ref struct
{
// Use T as a ref struct:
public void M(scoped T p)
{
// The parameter p must follow ref safety rules
}
}
Auf diese Weise können Typen wie System.Span<T> und System.ReadOnlySpan<T> ggf. mit generischen Algorithmen verwendet werden. Weitere Informationen finden Sie in den Updates für where
und im Artikel zum Programmierhandbuch über generische Einschränkungen .
ref struct
Schnittstellen
Vor C# 13 konnten ref struct
Typen keine Schnittstellen implementieren. Ab C# 13 können sie das. Sie können deklarieren, dass ein ref struct
Typ eine Schnittstelle implementiert. Um die Ref-Sicherheitsregeln zu gewährleisten, kann ein ref struct
Typ jedoch nicht in einen Schnittstellentyp konvertiert werden. Diese Konversion ist eine Boxing-Konversion und könnte die Ref-Sicherheit verletzen. Auf explizite Schnittstellenmethodendeklarationen in einem ref struct
kann nur über einen Typparameter zugegriffen werden, wenn dieser Typparameter allows ref struct
ist. Darüber hinaus müssen ref struct
Typen alle in einer Schnittstelle deklarierten Methoden implementieren, einschließlich dieser Methoden mit einer Standardimplementierung.
Weitere Informationen finden Sie in den Updates zu den Typen ,ref struct
und sowie zur Ergänzung der generischen Constraint allows ref struct
.
Weitere partielle Mitglieder
Sie können partial
Eigenschaften und partial
Indexer in C# 13 deklarieren. Partielle Eigenschaften und Indexer folgen im Allgemeinen denselben Regeln wie partial
-Methoden: Sie erstellen eine deklarierende -Deklaration und eine implementierende -Deklaration. Die Signaturen der beiden Deklarationen müssen übereinstimmen. Eine Einschränkung besteht darin, dass Sie keine automatische Eigenschaftsdeklaration für die Implementierung einer partiellen Eigenschaft verwenden können. Eigenschaften, die keinen Body deklarieren, gelten als Deklarationsdeklaration.
public partial class C
{
// Declaring declaration
public partial string Name { get; set; }
}
public partial class C
{
// implementation declaration:
private string _name;
public partial string Name
{
get => _name;
set => _name = value;
}
}
Erfahren Sie mehr in dem Artikel über partielle Mitglieder.
Priorität der Überladungsauflösung
In C# 13 erkennt der Compiler die OverloadResolutionPriorityAttribute, um eine Überladung über eine andere zu bevorzugen. Bibliotheksautoren können dieses Attribut verwenden, um sicherzustellen, dass eine neue, bessere Überladung gegenüber einer vorhandenen Überladung bevorzugt wird. Sie könnten zum Beispiel eine neue Überladung hinzufügen, die leistungsfähiger ist. Sie möchten keinen vorhandenen Code unterbrechen, der Ihre Bibliothek verwendet, aber Sie möchten, dass Benutzer bei der neu kompilierten Version auf die neue Version aktualisieren. Sie können Priorität der Überladungsauflösung verwenden, um dem Compiler mitzuteilen, welche Überladung bevorzugt werden soll. Überladungen mit der höchsten Priorität werden bevorzugt.
Dieses Feature ist für Bibliotheksautoren vorgesehen, um Mehrdeutigkeit beim Hinzufügen neuer Überladungen zu vermeiden. Bibliotheksautoren sollten dieses Attribut mit Bedacht verwenden, um Verwirrung zu vermeiden.
Das schlüsselwort field
Das kontextbezogene Schlüsselwort field
ist in C# 13 als Vorschaufeature enthalten. Das Token field
greift auf das vom Compiler synthetisierte Backing-Feld in einem Property-Accessor zu. Es ermöglicht Ihnen, einen Body für einen Accessor zu schreiben, ohne ein explizites Backing-Feld in Ihrer Typdeklaration zu deklarieren. Sie können einen Body für einen oder beide Accessoren für eine Eigenschaft mit Backing-Feld deklarieren.
Das feature field
wird als Vorschaufeature veröffentlicht. Wir möchten von Ihren Erfahrungen mit der Nutzung lernen. Es gibt eine potenziell fehlerhafte Änderung oder Verwirrung beim Lesen von Code in Typen, die auch ein Feld mit dem Namen field
enthalten. Sie können @field
oder this.field
verwenden, um zwischen dem schlüsselwort field
und dem Bezeichner zu unterscheiden.
Wichtig
Das Schlüsselwort field
ist ein Vorschaufeature in C# 13. Sie müssen .NET 9 verwenden und das <LangVersion>
Element auf preview
in Der Projektdatei festlegen, um das kontextbezogene Schlüsselwort field
zu verwenden.
Achten Sie darauf, die field
Schlüsselwortfunktion in einer Klasse zu verwenden, die ein Feld mit dem Namen field
hat. Das neue Schlüsselwort field
überlagert ein Feld namens field
im Bereich eines Eigenschafts-Accessors. Sie können entweder den Namen der field
Variablen ändern oder das @
-Token verwenden, um auf den field
Bezeichner als @field
zu verweisen. Sie erfahren mehr, wenn Sie die Spezifikation der Funktion für das field
Schlüsselwort lesen.
Wenn Sie diese Funktion ausprobieren und Feedback haben, fügen Sie es dem Feature-Issue im csharplang
Repository hinzu.