Partilhar via


Resolução de sobrecarga em C# 14 com parâmetros de intervalo

C# 14, que é lançado com o .NET 10, introduz novas conversões de 'span' embutidas de e regras de inferência de tipo. Essas alterações tornam as sobrecargas com parâmetros de extensão aplicáveis em mais cenários.

Comportamento anterior

Em C# 13 e anteriores, um método de extensão tomando um recetor ReadOnlySpan<T> ou Span<T> não era aplicável a um valor do tipo T[]. Portanto, somente métodos de extensão que não envolvem "span", como os da classe System.Linq.Enumerable, eram frequentemente utilizados em lambdas de expressão.

Novo comportamento

Em C# 14 e posteriores, métodos com parâmetros ReadOnlySpan<T> ou Span<T> podem participar da inferência de tipo ou ser usados como métodos de extensão em mais cenários. Isto permite que métodos baseados em span, como os da classe System.MemoryExtensions, se vinculem em mais cenários, incluindo dentro das lambdas de expressão, onde causarão exceções em tempo de execução quando compilados com interpretação.

Versão introduzida

.NET 10

Tipo de mudança de rutura

Esta alteração é uma mudança comportamental.

Motivo da mudança

O recurso de linguagem C# permite o design e uso simplificado da API (por exemplo, um método de extensão ReadOnlySpan<T> pode ser aplicado tanto a spans quanto a matrizes).

Se você precisar continuar usando a interpretação de expressão, certifique-se de que as sobrecargas não-span estejam vinculadas, por exemplo, lançando argumentos para os tipos exatos que a assinatura do método usa ou chamando os métodos de extensão como invocações estáticas explícitas:

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 afetadas