Compartir vía


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).

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);

APIs afectadas