Partager via


La résolution des surcharges en C# préfère les surcharges de type params étendue

C# 13 a ajouté la prise en charge des paramètres params déclarés avec des types de collection autres que les tableaux. En particulier, params ReadOnlySpan<T> et params Span<T> sont pris en charge, et la résolution des surcharges préfère un type d'étendue params à un type de tableau params lorsque les deux sont applicables.

.NET 9 a ajoutéparams des surcharges d'étendue pour diverses méthodes dans les bibliothèques .NET de base. Ces méthodes avaient des surcharges préexistantes qui prenaient des tableaux params. Lorsque vous recompilez le code avec des appels existants à ces méthodes où les arguments sont transmis sous forme développée, le compilateur se lie désormais à la surcharge de l'étendue params.

La nouvelle liaison entraîne une rupture potentielle pour les appels existants à ces surcharges dans les expressions lambda Expression, qui ne prennent pas en charge les instances ref struct. Dans ces cas, le compilateur C# 13 signale une erreur lors de la liaison avec la surcharge de l'étendue params.

Par exemple, considérez string.Join():

using System;
using System.Linq.Expressions;

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

Lorsqu’il est compilé avec .NET 8, l’appel est lié à Join(String, String[]), sans erreurs.

Lorsqu’il est compilé avec C# 13 et .NET 9, l’appel est lié à Join(String, ReadOnlySpan<String>)et, étant donné que l’appel se trouve dans une arborescence d’expressions , les erreurs suivantes sont signalées :

erreur CS8640 : L’arborescence d’expressions ne peut pas contenir de valeur de struct ref ou de type restreint « ReadOnlySpan ». erreur CS9226 : Une arborescence d’expressions ne peut pas contenir une forme développée de paramètres non-tableau.

Version introduite

.NET 9

Comportement précédent

Avant C# 13, les paramètres params étaient limités uniquement aux types de tableaux. Les appels à ces méthodes sous forme développée ont abouti uniquement à des instances de tableau implicites, qui sont prises en charge dans les expressions lambda Expression.

Nouveau comportement

Avec C# 13 et .NET 9, pour les méthodes avec des surcharges qui acceptent des types de tableaux params et des types de "span" params, la résolution de surcharge préfère la surcharge de "span" params. Un tel appel crée une instance d'étendue implicite sur le site d'appel. Pour les appels à l'intérieur d'expressions lambda Expression, l'instance d'étendue ref struct implicite est signalée comme une erreur de compilation.

Type de changement cassant

Cette modification peut affecter la compatibilité source .

Raison de la modification

Les nouvelles surcharges de méthode ont été ajoutées pour des raisons de performance. La prise en charge de l'étendue params permet au compilateur d'éviter une allocation pour l'argument params sur le site d'appel.

Si votre code est affecté, la solution de contournement recommandée consiste à appeler la méthode avec un tableau explicite afin que l’appel soit lié à la surcharge de tableau params.

Pour l’exemple précédent, utilisez new string[] { ... }:

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

API affectées

Voir aussi