Compartir a través de


La resolución de sobrecarga en C# prefiere las sobrecargas de tipo de intervalo params.

C# 13 agregó compatibilidad para parámetros params declarados con tipos de colecciones diferentes a arrays. En concreto, se admiten params ReadOnlySpan<T> y params Span<T>, y la resolución de sobrecarga prefiere un tipo de intervalo params en lugar de un tipo de matriz params cuando ambos son aplicables.

.NET 9 agregóparams sobrecargas de intervalo para varios métodos en las bibliotecas principales de .NET. Esos métodos tenían sobrecargas preexistentes que tomaban matrices params. Al volver a compilar código con llamadas existentes a esos métodos en los que los argumentos se pasan de forma expandida, el compilador ahora se enlazará a la sobrecarga de intervalo params.

El nuevo enlace conduce a un posible cambio importante para las llamadas existentes a esas sobrecargas dentro de expresiones lambda Expression, que no admiten instancias de ref struct. En esos casos, el compilador de C# 13 notifica un error al vincularse con la sobrecarga de intervalo params.

Por ejemplo, considere string.Join():

using System;
using System.Linq.Expressions;

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

Cuando se compila con .NET 8, la llamada se enlaza a Join(String, String[]), sin errores.

Cuando se compila con C# 13 y .NET 9, la llamada se enlaza a Join(String, ReadOnlySpan<String>)y porque la llamada está dentro de un árbol de expresiones de , se notifican los errores siguientes:

error CS8640: El árbol de expresiones no puede contener el valor de la estructura ref o el tipo restringido "ReadOnlySpan". error CS9226: Es posible que un árbol de expresiones no contenga una forma expandida de parámetros que no sean de matriz

Versión introducida

.NET 9

Comportamiento anterior

Antes de C# 13, los parámetros de params solo se limitaban a los tipos de matriz. Las llamadas a esos métodos en formato expandido solo dieron lugar a instancias implícitas de matriz, que se admiten en expresiones lambda Expression.

Nuevo comportamiento

Con C# 13 y .NET 9, para los métodos con sobrecargas que aceptan tipos de matriz params y tipos de intervalo params, la resolución de sobrecargas prefiere la sobrecarga de intervalo params. Esta llamada crea una instancia de intervalo implícita en el sitio de llamada. Para llamadas dentro de expresiones lambda Expression, la instancia de intervalo implícita ref struct se notifica como error de compilador.

Tipo de cambio disruptivo

Este cambio puede afectar a la compatibilidad de orígenes.

Motivo del cambio

Las nuevas sobrecargas de método se agregaron por razones de rendimiento. El intervalo params permite que el compilador evite una asignación para el argumento params en el punto de llamada.

Si su código se ve afectado, la solución alternativa recomendada es llamar al método con una matriz explícita para que la llamada se enlace a la sobrecarga de matriz params.

Para el ejemplo anterior, use new string[] { ... }:

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

APIs afectadas

Consulte también