使用跨度参数 C# 14 重载解析

C# 14 随 .NET 10 一同发布,引入了新的 内置跨度转换和类型推理规则。 这些更改使得带有跨度参数的重载在更多场景中适用。

以前的行为

在 C# 13 及更早版本中,采用 ReadOnlySpan<T>Span<T> 接收器的扩展方法不适用于类型 T[]的值。 因此,只有非跨度扩展方法(如 System.Linq.Enumerable 类中的方法)通常绑定到 Expression lambda 中。

新行为

在 C# 14 及更高版本中,具有 ReadOnlySpan<T>Span<T> 参数的方法可以参与类型推理,或在更多方案中用作扩展方法。 这使得基于范围的方法(如 System.MemoryExtensions 类中的方法)能够在多种场景中进行绑定,包括在表达式 lambda 中,当以解释模式编译时会导致运行时异常。

引入的版本

.NET 10

中断性变更的类型

此更改为行为更改

更改原因

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

受影响的 API