C# 4.0 引入選擇性參數與具名參數,大幅簡化方法多載與呼叫靈活度,特別在 Office 互操作中可避免大量 Type.Missing。
class Test {
// a 為必填,b、c 為選擇性參數並指定預設值
public void OptionalAndNamedParams(int a, string b = "", object c = "https://xianfen.net") {
Console.WriteLine($"a:{a}, b:{b}, c:{c}");
}
}
class Program {
static void Main() {
Test t = new Test();
t.OptionalAndNamedParams(1); // 使用預設值
t.OptionalAndNamedParams(2, "a"); // 依位置傳遞
t.OptionalAndNamedParams(3, c: "b", b: "a"); // 具名參數,順序可互換
t.OptionalAndNamedParams(4, c: "https://g.cn"); // 略過 b 直接指定 c
}
}
輸出:
a:1, b:, c:https://xianfen.net
a:2, b:a, c:https://xianfen.net
a:3, b:a, c:b
a:4, b:, c:https://g.cn
ref、out。編譯器在方法簽章加上 [Optional]、[DefaultParameterValue] 屬性:
.method public void OptionalAndNamedParams(int32 a,
[opt] string b,
[opt] object c) cil managed
{
.param [2] = "" // b 預設值
.param [3] = "https://www.xianfen.net" // c 預設值
}
等價於手寫:
public void OptionalAndNamedParams(int a,
[Optional, DefaultParameterValue("")] string b,
[Optional, DefaultParameterValue("https://www.xianfen.net")] object c)
呼叫 t.OptionalAndNamedParams(1) 時,編譯器將預設值直接內嵌至呼叫處:
IL_0006: ldloc.0
IL_0007: ldc.i4.1
IL_0008: ldstr "" // b 預設值內嵌
IL_000d: ldstr "https://www.xianfen.net" // c 預設值內嵌
IL_0012: callvirt instance void Test::OptionalAndNamedParams(int32,string,object)
版本控管風險:若類別庫更新預設值,呼叫端未重新編譯仍使用舊預設值,可能導致行為不一致。
新增多載 void OptionalAndNamedParams(int a, string b) 後,呼叫 t.OptionalAndNamedParams(2, "a") 會優先匹配參數完全一致的多載,而非選擇性參數版本。