Resolución de sobrecarga en C# 14 con parámetros span
C# 14, que se incluye con .NET 10, presenta nuevas conversiones de span integradas y reglas de inferencia de tipos. Estos cambios realizan sobrecargas con parámetros span aplicables en más escenarios.
Comportamiento anterior
En C# 13 y versiones anteriores, un método de extensión que toma como receptor un ReadOnlySpan<T>
o Span<T>
no era aplicable a un valor de tipo T[]
. Por lo tanto, solo los métodos de extensión no relacionados con span como los de la clase System.Linq.Enumerable
normalmente se enlazaban dentro de las lambdas de expresión.
Nuevo comportamiento
En C# 14 y versiones posteriores, los métodos con parámetros ReadOnlySpan<T>
o Span<T>
pueden participar en la inferencia de tipos o usarse como métodos de extensión en más escenarios. Esto hace que los métodos basados en intervalos, como los de la clase System.MemoryExtensions
, se enlacen en más escenarios, incluido dentro de lambdas de expresión, donde provocarán excepciones en tiempo de ejecución cuando se compilen con interpretación.
Versión introducida
.NET 10 Preview 1
Tipo de cambio disruptivo
Este cambio es un cambio de comportamiento .
Motivo del cambio
La característica del lenguaje C# permite un uso y diseño de API simplificados (por ejemplo, un método de extensión ReadOnlySpan<T> se puede aplicar tanto a intervalos como a matrices).
Acción recomendada
Si necesita seguir utilizando la interpretación de expresiones, asegúrese de que las sobrecargas no relacionadas con el uso de span estén vinculadas, por ejemplo, convirtiendo los argumentos a los tipos exactos que requiere la firma del método o llamando a los métodos de extensión de manera explícita como invocaciones estáticas:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
M((array, num) => array.Contains(num)); // fails, binds to MemoryExtensions.Contains
M((array, num) => ((IEnumerable<int>)array).Contains(num)); // ok, binds to Enumerable.Contains
M((array, num) => array.AsEnumerable().Contains(num)); // ok, binds to Enumerable.Contains
M((array, num) => Enumerable.Contains(array, num)); // ok, binds to Enumerable.Contains
void M(Expression<Func<int[], int, bool>> e) => e.Compile(preferInterpretation: true);