Neuerungen in C# 10

Mit Version 10 wird die Sprache C# um die folgenden Features und Verbesserungen erweitert:

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

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

Datensatzstrukturen

Sie können Werttyp-Datensätze deklarieren, indem Sie entweder die record struct- oder readonly record struct- Deklaration verwenden. Sie können nun mit der Deklaration record class verdeutlichen, dass record ein Referenztyp ist.

Verbesserungen von Strukturtypen

In C# 10 werden die folgenden Verbesserungen im Zusammenhang mit Strukturtypen eingeführt:

  • Sie können einen parameterlosen Konstruktor für eine Instanz in einem Strukturtyp deklarieren und ein Instanzfeld oder eine Instanzeigenschaft in der zugehörigen Deklaration initialisieren. Weitere Informationen finden Sie im Abschnitt Parameterlose Konstruktoren und Feldinitialisierer des Artikels Strukturtypen.
  • Der linke Operand des with-Ausdrucks kann einen beliebigen Strukturtyp oder einen anonymen Typ (Verweistyp) aufweisen.

Handler für interpolierte Zeichenfolgen

Sie können einen Typ erstellen, der die resultierende Zeichenfolge aus einem interpolierten Zeichenfolgenausdruck erstellt. Die .NET-Bibliotheken verwenden dieses Feature in vielen APIs. Sie können einen Handler anhand dieses Tutorials erstellen.

Globale using-Anweisungen

Sie können den global-Modifizierer einer beliebigen using-Anweisung hinzufügen, um den Compiler anzuweisen, dass die Direktive für alle Quelldateien in der Kompilierung gilt. Dies sind in der Regel alle Quelldateien in einem Projekt.

Dateibezogene Namespacedeklaration

Sie können eine neue Form der namespace-Deklaration verwenden, um zu deklarieren, dass alle nachfolgenden Deklarationen Member des deklarierten Namespace sind:

namespace MyNamespace;

Diese neue Syntax spart sowohl horizontal als auch vertikal Platz für namespace-Deklarationen.

Muster für erweiterte Eigenschaften

Ab C# 10 können Sie auf geschachtelte Eigenschaften oder Felder innerhalb eines Eigenschaftsmusters verweisen. Beispielsweise ein Muster der Form

{ Prop1.Prop2: pattern }

ist in C# 10 und höher gültig und entspricht

{ Prop1: { Prop2: pattern } }

(In C# 8.0 und höher gültig)

Weitere Informationen finden Sie unter Eigenschaftsmuster im Hinweis zum Featurevorschlag. Weitere Informationen zu Eigenschaftsmustern finden Sie im Abschnitt Eigenschaftsmuster des Artikels Muster.

Verbesserungen bei Lambdaausdrücken

C# 10 umfasst viele Verbesserungen der Verwendung von Lambdaausdrücken:

  • Lambdaausdrücke können einen natürlichen Typ umfassen, wobei der Compiler einen Delegattyp aus dem Lambdaausdruck oder der Methodengruppe ableiten kann.
  • Lambdaausdrücke können einen Rückgabetyp deklarieren, wenn dieser vom Compiler nicht abgeleitet werden kann.
  • Attribute können auf Lambdaausdrücke angewendet werden.

Durch diese Features ähneln Lambdaausdrücke eher Methoden und lokalen Funktionen. Sie erleichtern die Verwendung von Lambdaausdrücken, ohne eine Variable eines Delegattyps zu deklarieren, und sie funktionieren problemlos mit den neuen minimalen ASP.NET Core-APIs.

Konstante interpolierte Zeichenfolgen

In C# 10 können Zeichenfolgen vom Typ const mithilfe der Zeichenfolgeninterpolation initialisiert werden, wenn alle Platzhalter selbst konstante Zeichenfolgen sind. Durch Zeichenfolgeninterpolation können besser lesbare konstante Zeichenfolgen erzeugt werden, während Sie konstante Zeichenfolgen zur Verwendung in Ihrer Anwendung erstellen. Die Platzhalterausdrücke können keine numerischen Konstanten sein, da diese Konstanten zur Laufzeit in Zeichenfolgen konvertiert werden. Die aktuelle Kultur kann sich auf die Zeichenfolgendarstellung auswirken. Weitere Informationen finden Sie in der Sprachreferenz zu const-Ausdrücken.

Datensatztypen können ToString versiegeln

In C# 10 können Sie den sealed-Modifizierer hinzufügen, wenn Sie ToString in einem Datensatztyp überschreiben. Das Versiegeln der ToString-Methode verhindert, dass der Compiler eine ToString-Methode für abgeleitete Datensatztypen synthetisiert. Es sealedToString wird sichergestellt, dass alle abgeleiteten Datensatztypen die ToString in einem allgemeinen Basisdatensatztyp definierte Methode verwenden. Weitere Informationen über dieses Feature finden Sie im Artikel zu Datensätzen.

Zuweisung und Deklaration in derselben Dekonstruktion

Diese Änderung hebt eine Einschränkung aus früheren Versionen von C# auf. Zuvor konnte eine Dekonstruktion alle Werte vorhandenen Variablen zuweisen oder neu deklarierte Variablen initialisieren:

// Initialization:
(int x, int y) = point;

// assignment:
int x1 = 0;
int y1 = 0;
(x1, y1) = point;

Diese Einschränkung wird in C# 10 aufgehoben:

int x = 0;
(x, int y) = point;

Verbesserte eindeutige Zuweisung

Vor C# 10 gab es viele Szenarios, in denen die eindeutige Zuweisung und die Analyse des NULL-Status Warnungen generierten, die falsch positiv waren. Diese umfassten im Allgemeinen Vergleiche mit booleschen Konstanten, den Zugriff auf eine Variable nur in den Anweisungen true oder false in einer if-Anweisung und NULL-Sammelausdrücke. In diesen Beispielen wurden Warnungen in früheren Versionen von C# generiert, aber nicht in C# 10:

string representation = "N/A";
if ((c != null && c.GetDependentValue(out object obj)) == true)
{
   representation = obj.ToString(); // undesired error
}

// Or, using ?.
if (c?.GetDependentValue(out object obj) == true)
{
   representation = obj.ToString(); // undesired error
}

// Or, using ??
if (c?.GetDependentValue(out object obj) ?? false)
{
   representation = obj.ToString(); // undesired error
}

Die wichtigste Auswirkung dieser Verbesserung ist, dass die Warnungen für die eindeutige Zuweisung und die Analyse des NULL-Status genauer sind.

AsyncMethodBuilder-Attribut für Methoden

In C# 10 und höher können Sie zusätzlich zur Angabe des Methodengeneratortyps für alle Methoden, die einen bestimmten taskähnlichen Typ zurückgeben, einen anderen Generator für asynchrone Methoden für eine einzelne Methode angeben. Ein benutzerdefinierter asynchroner Methoden-Generator ermöglicht erweiterte Szenarios der Leistungsoptimierung, in denen eine bestimmte Methode von einem benutzerdefinierten Generator profitieren kann.

Weitere Informationen finden Sie im Abschnitt zu AsyncMethodBuilder im Artikel zu vom Compiler gelesenen Attributen.

CallerArgumentExpression-Attributdiagnose

Sie können System.Runtime.CompilerServices.CallerArgumentExpressionAttribute verwenden, um einen Parameter anzugeben, den der Compiler durch die Textdarstellung eines anderen Arguments ersetzt. Mit diesem Feature können Bibliotheken spezifischere Diagnosen erstellen. Der folgende Code testet eine Bedingung. Wenn die Bedingung FALSE ist, enthält die Ausnahmemeldung die Textdarstellung des Arguments, das an condition übergeben wird:

public static void Validate(bool condition, [CallerArgumentExpression("condition")] string? message=null)
{
    if (!condition)
    {
        throw new InvalidOperationException($"Argument failed validation: <{message}>");
    }
}

Weitere Informationen zu diesem Feature finden Sie im Artikel zu den Aufruferinformationsattributen im Abschnitt zur Sprachreferenz.

Verbessertes #line-Pragma

C# 10 unterstützt ein neues Format für das #line-Pragma. Sie verwenden wahrscheinlich nicht das neue Format, aber Sie werden seine Auswirkungen erkennen. Die Verbesserungen ermöglichen eine präzisere Ausgabe in domänenspezifischen Sprachen (Domain-Specific Languages, DSLs) wie Razor. Die Razor-Engine nutzt diese Verbesserungen, um die Debugfunktion zu verbessern. Sie werden feststellen, dass Debugger Ihre Razor-Quelle genauer hervorheben können. Weitere Informationen zur neuen Syntax finden Sie im Artikel zu Präprozessoranweisungen in der Sprachreferenz. Sie können auch die Featurespezifikation für Razor-basierte Beispiele lesen.