Udostępnij za pośrednictwem


Rozpoznawanie przeciążeń w języku C# preferuje przeciążenia typu span params.

Język C# 13 dodał obsługę parametrów params zadeklarowanych przy użyciu typów kolekcji innych niż tablice. W szczególności obsługiwane są params ReadOnlySpan<T> i params Span<T>, a rozdzielanie przeciążenia preferuje typ zakresu params zamiast typu tablicowego params, gdy oba mają zastosowanie.

Platforma .NET 9 dodała przeciążenia params typu span dla różnych metod w bibliotekach podstawowych .NET. Te metody miały wcześniej istniejące przeciążenia obsługujące tablice params. Podczas ponownego kompilowania kodu z istniejącymi wywołaniami tych metod, gdzie argumenty są przekazywane w postaci rozwiniętej, kompilator powiąże teraz z funkcją przeciążeniową zakresu params.

Nowe powiązanie prowadzi do potencjalnej zmiany powodującej niezgodność istniejących wywołań dla tych przeciążeń w Expression wyrażeniach lambda, które nie obsługują ref struct wystąpień. W takich przypadkach kompilator języka C# 13 zgłasza błąd podczas wiązania z przeciążeniem params span.

Rozważmy na przykład string.Join():

using System;
using System.Linq.Expressions;

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

Po skompilowaniu przy użyciu platformy .NET 8 wywołanie wiąże się z Join(String, String[]), bez błędów.

Po skompilowaniu przy użyciu języków C# 13 i .NET 9 wywołanie wiąże się z Join(String, ReadOnlySpan<String>)i dlatego, że wywołanie znajduje się w drzewie wyrażeń , są zgłaszane następujące błędy:

błąd CS8640: Drzewo wyrażeń nie może zawierać wartości struktury ref lub typu ograniczonego "ReadOnlySpan". błąd CS9226: Drzewo wyrażeń nie może zawierać rozszerzonej formy parametrów innego typu niż tablica

Wprowadzona wersja

.NET 9

Poprzednie zachowanie

Przed C# 13 parametry params były ograniczone tylko do typów tablic. Wywołania tych metod w rozszerzonej formie powodowały jedynie niejawne wystąpienia tablic, które są obsługiwane w wyrażeniach lambda Expression.

Nowe zachowanie

Dla języka C# 13 i .NET 9 w przypadku metod z przeciążeniami przyjmującymi typy tablic params i typy span params, rozdzielanie przeciążeń preferuje przeciążenie span params. Takie wywołanie tworzy niejawne wystąpienie zakresu w miejscu wywołania. W przypadku wywołań w Expression wyrażeniach lambda wystąpienie niejawne ref struct span jest zgłaszane jako błąd kompilatora.

Typ zmiany powodującej niezgodność

Ta zmiana może mieć wpływ na zgodność źródła .

Przyczyna zmiany

Nowe przeciążenia metody zostały dodane ze względów wydajności. params obsługa zakresu umożliwia kompilatorowi uniknięcie alokacji argumentu params w miejscu wywołania.

Jeśli dotyczy to kodu, zalecanym obejściem jest wywołanie metody z jawną tablicą, aby wywołanie wiązało się z przeciążeniem tablicy params.

W poprzednim przykładzie użyj new string[] { ... }:

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

Interfejsy API, których dotyczy problem

Zobacz też