Freigeben über


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:

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 \eals zeichenliterale Escapesequenz für dasESCAPE Zeichen Unicode U+001B verwenden. Zuvor haben Sie \u001b oder \x1bverwendet. 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 returnverwenden) 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 structhinzufü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 structist. 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 fieldhat. 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 @fieldzu 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.

Siehe auch