Freigeben über


Neuerungen in C# 12

C# 12 bietet die folgenden neuen Features. Sie können diese Features mit der neuesten Visual Studio 2022-Version oder dem .NET 8 SDKtesten.

C# 12 wird in .NET 8 unterstützt. Weitere Informationen finden Sie unter C#-Sprachversionsverwaltung.

Sie können das neueste .NET 8 SDK über die .NET-Downloadseite herunterladen. Sie können auch die Version Visual Studio 2022 herunterladen, die das .NET SDK 8 enthält.

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.

Primäre Konstruktoren

Sie können jetzt in allen class- und struct-Elementen primäre Konstruktoren erstellen. Primäre Konstruktoren sind nicht mehr auf record-Typen beschränkt. Parameter für primäre Konstruktoren sind für den gesamten Text der Klasse gültig. Um sicherzustellen, dass alle Parameter für primäre Konstruktoren definitiv zugewiesen sind, müssen alle explizit deklarierten Konstruktoren den primären Konstruktor mithilfe der Syntax this() aufrufen. Das Hinzufügen eines primären Konstruktors zu einer class verhindert, dass der Compiler einen impliziten parameterlosen Konstruktor deklariert. In einem struct-Element initialisiert der implizite parameterlose Konstruktor alle Felder, einschließlich der Parameter für primäre Konstruktoren im 0-Bit-Muster.

Der Compiler generiert öffentliche Eigenschaften für die Parameter für primäre Konstruktoren nur in record-Typen: entweder record class oder record struct. Bei Klassen und Strukturen, die nicht vom Typ „record“ sind, ist dieses Verhalten für Parameter für primäre Konstruktoren möglicherweise nicht immer geeignet.

Im Tutorial zum Erkunden von primären Konstruktoren und im Artikel zu Instanzkonstruktoren erfahren Sie mehr über primäre Konstruktoren.

Sammlungsausdrücke

Sammlungsausdrücke führen eine neue nicht ausführliche Syntax ein, um allgemeine Sammlungswerte zu erstellen. Das Inlining anderer Sammlungen in diese Werte ist mithilfe des Spread-Operators .. möglich.

Mehrere sammlungsähnliche Typen können erstellt werden, ohne dass externe BCL-Unterstützung erforderlich ist. Zu diesen Typen zählen:

Die folgenden Beispiele zeigen Verwendungsmöglichkeiten der Sammlungsausdrücke:

// Create an array:
int[] a = [1, 2, 3, 4, 5, 6, 7, 8];

// Create a list:
List<string> b = ["one", "two", "three"];

// Create a span
Span<char> c  = ['a', 'b', 'c', 'd', 'e', 'f', 'h', 'i'];

// Create a jagged 2D array:
int[][] twoD = [[1, 2, 3], [4, 5, 6], [7, 8, 9]];

// Create a jagged 2D array from variables:
int[] row0 = [1, 2, 3];
int[] row1 = [4, 5, 6];
int[] row2 = [7, 8, 9];
int[][] twoDFromVariables = [row0, row1, row2];

Der Spread-Operator.. ersetzt in einem Sammlungsausdruck sein Argument durch die Elemente aus dieser Sammlung. Das Argument muss ein Sammlungstyp sein. Anhand der folgenden Beispiele wird die Funktionsweise des Spread-Operators erläutert:

int[] row0 = [1, 2, 3];
int[] row1 = [4, 5, 6];
int[] row2 = [7, 8, 9];
int[] single = [.. row0, .. row1, .. row2];
foreach (var element in single)
{
    Console.Write($"{element}, ");
}
// output:
// 1, 2, 3, 4, 5, 6, 7, 8, 9,

Der Operand eines Spread-Operators ist ein Ausdruck, der aufgelistet werden kann. Der Spread-Operator wertet jedes Element des Enumerationsausdrucks aus.

Sie können Sammlungsausdrücke überall verwenden, wo Sie eine Sammlung von Elementen benötigen. Sie können den Anfangswert für eine Auflistung angeben oder als Argumente an Methoden übergeben werden, die Sammlungstypen verwenden. Weitere Informationen zu Sammlungsausdrücken finden Sie im Sprachreferenzartikel zu Sammlungsausdrücken oder der Featurespezifikation.

ref readonly-Parameter

C# hat in-Parameter als Möglichkeit zum Übergeben von lesegeschützten Verweisen hinzugefügt. in-Parameter ermöglichen Variablen und Werte und können ohne Anmerkung für Argumente verwendet werden.

Das Hinzufügen von ref readonly-Parametern ermöglicht mehr Klarheit für APIs, die ref-Parameter oder in-Parameter verwenden können:

Weitere Informationen zu ref readonly-Parametern finden Sie im Artikel über Parametermodifizierer in der Sprachreferenz oder in der Funktionsspezifikation Ref readonly-Parameter.

Standardmäßige Lambdaparameter

Sie können jetzt Standardwerte für Parameter für Lambdaausdrücke definieren. Syntax und Regeln entsprechen dem Hinzufügen von Standardwerten für Argumente zu einer beliebigen Methode oder lokalen Funktion.

Weitere Informationen zu Standardparametern für Lambdaausdrücke finden Sie im Artikel zu Lambdaausdrücken.

Alias für beliebigen Typ

Sie können die Aliasanweisung using verwenden, um nicht nur benannten Typen, sondern beliebigen Typen einen Alias zuzuweisen. Das bedeutet, dass Sie semantische Aliase für Tupeltypen, Arraytypen, Zeigertypen oder andere unsichere Typen erstellen können. Weitere Informationen finden Sie in der Featurespezifikation.

Inlinearrays

Inlinearrays werden vom Laufzeitteam und anderen Bibliotheksautoren verwendet, um die Leistung in Ihren Apps zu verbessern. Inlinearrays ermöglichen es einem Entwickler, ein Array mit fester Größe in einem struct-Typ zu erstellen. Eine Struktur mit einem Inlinepuffer sollte Leistungseigenschaften aufweisen, die einem unsicheren Puffer mit fester Größe ähneln. Sie werden wahrscheinlich nicht Ihre eigenen Inlinearrays deklarieren, aber Sie werden sie transparent verwenden, wenn sie als System.Span<T>- oder System.ReadOnlySpan<T>-Objekte von Laufzeit-APIs bereitgestellt werden.

Ein Inlinearray wird ähnlich wie das folgende struct deklariert:

[System.Runtime.CompilerServices.InlineArray(10)]
public struct Buffer
{
    private int _element0;
}

Sie verwenden sie wie jedes andere Array:

var buffer = new Buffer();
for (int i = 0; i < 10; i++)
{
    buffer[i] = i;
}

foreach (var i in buffer)
{
    Console.WriteLine(i);
}

Der Unterschied besteht darin, dass der Compiler bekannte Informationen zu einem Inlinearray nutzen kann. Sie nutzen wahrscheinlich Inlinearrays wie jedes andere Array. Weitere Informationen zum Deklarieren von Inlinearrays finden Sie in der Sprachreferenz zu struct-Typen.

Experimentelles Attribut

Typen, Methoden oder Assemblys können mit System.Diagnostics.CodeAnalysis.ExperimentalAttribute gekennzeichnet werden, um eine experimentelle Funktion anzugeben. Der Compiler gibt eine Warnung aus, wenn Sie auf eine Methode zugreifen oder Anmerkungen mit ExperimentalAttribute eingeben. Alle Typen, die in einer Assembly enthalten sind, die mit dem Experimental-Attribut gekennzeichnet ist, sind experimentell. Weitere Informationen finden Sie im Artikel Vom Compiler gelesene allgemeinene Attribute oder in der Funktionspezifikation.

Interceptors

Warnung

Interceptors sind ein experimentelles Feature, das im Vorschaumodus von C# 12 verfügbar ist. Das Feature kann in einer zukünftigen Version Breaking Changes unterliegen oder entfernt werden. Daher wird es für Produktions- oder freigegebene Anwendungen nicht empfohlen.

Um Interceptors verwenden zu können, muss das Benutzerprojekt die Eigenschaft <InterceptorsPreviewNamespaces> angeben. Dies ist eine Liste von Namespaces, die Interceptors enthalten dürfen.

Beispiel: <InterceptorsPreviewNamespaces>$(InterceptorsPreviewNamespaces);Microsoft.AspNetCore.Http.Generated;MyLibrary.Generated</InterceptorsPreviewNamespaces>

Ein Interceptor ist eine Methode, die einen Aufruf an eine abfangbare Methode zur Kompilierzeit durch einen Aufruf an sich selbst deklarativ ersetzen kann. Diese Ersetzung erfolgt, indem der Interceptor die Quellspeicherorte der Aufrufe deklariert, die er abfängt. Interceptors bieten eine eingeschränkte Möglichkeit zum Ändern der Semantik von vorhandenem Code durch Hinzufügen von neuem Code zu einer Kompilierung, z. B. in einem Quellgenerator.

Ein Interceptor wird als Teil eines Quellgenerators zum Ändern verwendet, anstatt Code zu einer vorhandenen Quellkompilierung hinzuzufügen. Der Quellgenerator ersetzt Aufrufe an eine abfangbare Methode durch einen Aufruf an die Interceptor-Methode.

Wenn Sie daran interessiert sind, mit Interceptors zu experimentieren, können Sie mehr erfahren darüber in der Featurespezifikation erfahren. Wenn Sie das Feature verwenden, stellen Sie sicher, dass Sie hinsichtlich aller Änderungen in der Funktionsspezifikation für diese experimentelle Funktion auf dem neuesten Stand bleiben. Wenn die Funktion fertiggestellt ist, werden wir auf dieser Website weitere Leitfäden hinzufügen.

Siehe auch