Freigeben über


Die Überladungsauflösung von C# bevorzugt params Span-Typ Überladungen

C# 13 hat Unterstützung für params Parameter hinzugefügt, die mit anderen Sammlungstypen als Arrays deklariert wurden. Insbesondere params ReadOnlySpan<T> und params Span<T> werden unterstützt, und die Überladungsauflösung bevorzugt einen params-Span-Typ gegenüber einem params-Arraytyp, wenn beide anwendbar sind.

.NET 9 fügte params span-Überladungen für verschiedene Methoden in den .NET Core-Bibliotheken hinzu. Für diese Methoden gab es bereits Überladungen, die params Arrays verwendeten. Wenn Sie Code mit bestehenden Aufrufen dieser Methoden, bei denen Argumente in erweiterter Form übergeben werden, neu kompilieren, bindet der Compiler jetzt an die params Span-Überladung.

Die neue Bindung führt zu einer potenziell fehlerhaften Änderung bei bestehenden Aufrufen dieser Überladungen innerhalb von Expression-Lambda-Ausdrücken, die ref struct-Instanzen nicht unterstützen. In diesen Fällen meldet der C# 13-Compiler beim Binden an die params Spanüberladung einen Fehler.

Ziehen Sie beispielsweise string.Join() in Betracht:

using System;
using System.Linq.Expressions;

Expression<Func<string, string, string>> join =
    (x, y) => string.Join("", x, y);

Beim Kompilieren mit .NET 8 bindet der Aufruf ohne Fehler an Join(String, String[]).

Bei der Kompilierung mit C# 13 und .NET 9 bindet sich der Aufruf an Join(String, ReadOnlySpan<String>), und da sich der Aufruf in einem Ausdrucksbaum befindet, werden die folgenden Fehler gemeldet.

Error CS8640: Ausdrucksbaum kann keinen Wert von ref struct oder vom Einschränkungstyp ‚ReadOnlySpan‘ enthalten. Fehler CS9226: Ein Ausdrucksbaum darf keine erweiterte Form von Nicht-Array-Params enthalten

Eingeführte Version

.NET 9

Vorheriges Verhalten

Vor C# 13 params waren Parameter nur auf Arraytypen beschränkt. Aufrufe dieser Methoden in erweiterter Form führten nur zu impliziten Arrayinstanzen, die in Expression Lambda-Ausdrücken unterstützt werden.

Neues Verhalten

Mit C# 13 und .NET 9 bevorzugt die Überladungsauflösung für Methoden mit Überladungen, die params Array-Typen und params Span-Typen annehmen, die params Span-Überladung. Ein solcher Aufruf erstellt eine implizite Span-Instanz an der Aufrufstelle. Bei Aufrufen innerhalb von Expression Lambda-Ausdrücken wird die implizite ref struct Span-Instanz als Compilerfehler gemeldet.

Art der einschneidenden Änderung

Diese Änderung kann sich auf die Quellkompatibilität auswirken.

Grund für Änderung

Die neuen Methodenüberladungen wurden aus Leistungsgründen hinzugefügt. params Die Span-Unterstützung ermöglicht es dem Compiler, eine Zuordnung für das params Argument an der Aufrufwebsite zu vermeiden.

Wenn Ihr Code betroffen ist, empfiehlt es sich, die Methode mit einem expliziten Array aufzurufen, damit der Aufruf an die params Arrayüberladung gebunden wird.

Verwenden Sie new string[] { ... } für das vorherige Beispiel:

Expression<Func<string, string, string>> join =
    (x, y) => string.Join("", new string[] { x, y });

Betroffene APIs

Siehe auch