共用方式為


C# 多載解析偏好 params 範圍類型多載

C# 13 已新增對使用非陣列集合類型宣告的 params 參數的支持。 特別是支援 params ReadOnlySpan<T>params Span<T>,而且當兩者都適用時,多載解析偏好 params 範圍類型,而不是 params 陣列類型。

.NET 9 針對核心 .NET 連結庫中各種方法 新增 params 範圍多載。 這些方法具有已存在的重載,可以接受 params 陣列。 當您使用現有呼叫重新編譯程式代碼時,這些方法的自變數會以展開形式傳遞,編譯程式現在會繫結至 params 範圍多載。

新的綁定將導致目前在 Expression Lambda 表達式中呼叫這些多載發生潛在中斷變更,因為 lambda 表達式不支援 ref struct 實例。 在這些情況下,C# 13 編譯程式會在系結至 params 範圍多載時報告錯誤。

例如,請考慮 string.Join()

using System;
using System.Linq.Expressions;

Expression<Func<string, string, string>> join =
    (x, y) => string.Join("", x, y);

使用 .NET 8 編譯時,呼叫會系結至 Join(String, String[]),而不會發生錯誤。

使用 C# 13 和 .NET 9 編譯時,呼叫會系結至 Join(String, ReadOnlySpan<String>),而且因為呼叫位於 表達式樹狀結構內,因此會報告下列錯誤:

錯誤 CS8640:表達式樹狀結構不能包含 ref 結構或受限制類型 'ReadOnlySpan' 的值。 錯誤 CS9226:表達式樹狀結構可能不會包含非數位列參數的展開形式

引進的版本

.NET 9

先前的行為

在 C# 13 之前,params 參數僅限於矩陣類型。 以展開形式呼叫這些方法時,僅會產生隱式陣列實例,而 lambda 表達式 Expression 支援這些實例。

新行為

使用 C# 13 和 .NET 9 時,對於包含 params 陣列型別和 params 跨度型別的多載方法,多載解析時偏好 params 跨度多載。 這類呼叫會在呼叫點建立隱含的範圍實例。 對於 Expression lambda 表達式內的呼叫,隱含 ref struct 範圍實例會被報告為編譯錯誤。

中斷性變更的類型

這項變更可能會影響 來源相容性

變更的原因

基於效能考慮,已新增新方法多載。 params span 支援可讓編譯程式避免在呼叫點配置 params 參數。

如果您的程式代碼受到影響,建議的因應措施是使用明確的數位列呼叫 方法,讓呼叫系結至 params 陣列多載。

針對上述範例,請使用 new string[] { ... }

Expression<Func<string, string, string>> join =
    (x, y) => string.Join("", new string[] { x, y });

受影響的 API

另請參閱