Condividi tramite


Risoluzione dell'overload C# 14 con parametri span

C# 14, fornito con .NET 10, introduce nuove conversioni di intervalli predefiniti e regole di inferenza dei tipi. Queste modifiche rendono gli overload con parametri span applicabili in altri scenari.

Comportamento precedente

In C# 13 e versioni precedenti, un metodo di estensione che accetta un ricevitore ReadOnlySpan<T> o Span<T> non è applicabile a un valore di tipo T[]. Pertanto, in genere solo i metodi di estensione non span, come quelli della classe System.Linq.Enumerable, erano associati all'interno delle lambda di espressione.

Nuovo comportamento

In C# 14 e versioni successive, i metodi con ReadOnlySpan<T> o Span<T> parametri possono partecipare all'inferenza del tipo o essere usati come metodi di estensione in più scenari. In questo modo, metodi basati su intervalli come quelli della classe System.MemoryExtensions vengono associati in più scenari, incluse le espressioni lambda in cui causeranno eccezioni in fase di esecuzione quando vengono compilate con interpretazione.

Versione introdotta

.NET 10 Preview 1

Tipo di modifica che causa un'interruzione

Questa modifica è una modifica comportamentale .

Motivo della modifica

La funzionalità del linguaggio C# consente di semplificare la progettazione e l'utilizzo delle API( ad esempio, un metodo di estensione ReadOnlySpan<T> può essere applicato sia a intervalli che a matrici).

Se è necessario continuare a usare l'interpretazione di Expression, assicurarsi che gli overload non-span siano associati, ad esempio, trasformando gli argomenti nei tipi esatti che la firma del metodo accetta o chiamando i metodi di estensione come invocazioni statiche esplicite.

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

API interessate