JetBrains Rider 2025.3 Help

代码检查:C# 14 在带有 span 参数的重载解析中的重大变化

C# 14 引入了新的 内置 span 转换和类型推断规则。 这使得带有 span 参数的重载在更多场景中适用,但也带来了一些 重大变化

JetBrains Rider 会识别可能受到这些重大变化影响的位置,并建议对其进行审查。 并非所有发生更改的行为都会在编译或运行时导致错误,因此无需修复所有建议项。 建议在审查所有发生项并修复可能在编译或运行时导致错误的项后,禁用此检查。

之前的行为

在 C# 14 之前,带有 ReadOnlySpan<T>Span<T> 参数的扩展方法无法直接应用于类型为 T[] 的数组。 因此,在处理数组时,编译器仅在方法解析期间选择非 span 扩展方法(例如,在 System.Linq.Enumerable 类中定义的方法)。

新的行为

从 C# 14 开始,接受 ReadOnlySpan<T>Span<T> 参数的方法具备了类型推断的扩展能力,并可作为更广泛上下文中的扩展方法使用。 因此,在诸如 System.MemoryExtensions 等库中定义的基于 span 的方法现在可适用于其他场景,在这些场景中,它们可能会意外地引发运行时异常。

示例

对于协变数组,在选择使用 Span<T> 的重载时于运行时 ArrayTypeMismatchException

string[] strings = new[] { "a" }; M(strings); void M(object[] possibleCovariantArray) { // ok with C# 13 because it uses overload with IEnumerable<T>, // but in C# 14, ArrayTypeMismatchException is thrown at runtime // when converting a covariant array to Span<object> Util.DoSomething(possibleCovariantArray); } static class Util { public static void DoSomething<T>(IEnumerable<T> e) => Console.Write("IEnumerable<T>"); public static void DoSomething<T>(Span<T> s) => Console.Write("Span<T>"); }

由于重载解析规则发生更改,导致编译错误:

string[] strings = new[] { "a" }; // C# 13 uses overload with IEnumerable<T>, which has a return type, // but C# 14 uses overload with Span<T>, which has no return type _ = strings.Reverse(); static class Util { public static IEnumerable<T> Reverse<T>(this IEnumerable<T> e) => throw new NotImplementedException(); public static void Reverse<T>(this Span<T> s) => throw new NotImplementedException(); }

在使用解释编译的表达式 lambda 中发生运行时异常:

using System.Linq.Expressions; // ok with C# 13, but causes a runtime exception in C# 14 // because it uses overload with ReadOnlySpan<T> M((array, num) => array.Contains(num)); void M(Expression<Func<int[], int, bool>> e) => e.Compile(preferInterpretation: true);

在官方 Microsoft 文档中了解更多信息:

最后修改日期: 2025年 12月 5日