使用範圍參數的 C# 14 重載解析
C# 14 隨 .NET 10 發布,引進新的 內建範圍轉換和型別推斷規則。 這些變更使得具有範圍參數的多載在更多情況下可應用。
先前的行為
在 C# 13 和更早版本中,採用 ReadOnlySpan<T>
或 Span<T>
接收器的擴充方法不適用於 類型 T[]
的值。 因此,只有非 Span 擴充方法,例如來自 System.Linq.Enumerable
類別的方法,通常會系結在 Expression lambda 內。
新行為
在 C# 14 和更新版本中,具有 ReadOnlySpan<T>
或 Span<T>
參數的方法可以參與型別推斷,或在更多案例中當做擴充方法使用。 這讓基於範圍的方法如同 System.MemoryExtensions
類別中的方法在更多情境中系結,包括在 Expression Lambda 表達式中,這在以解譯方式編譯時會導致執行時例外。
引進的版本
.NET 10 Preview 1
中斷性變更的類型
這項變更是 行為上的變化。
變更的原因
C# 語言功能允許更簡化的 API 設計和使用(例如,一個 ReadOnlySpan<T> 擴充方法可以同時應用於 Span 和陣列)。
建議的動作
如果您需要繼續使用表達式解譯,請確定非範圍多載已系結,例如,將自變數轉換成方法簽章採用或呼叫擴充方法的確切類型,作為明確的靜態調用:
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);