.method public hidebysig instance void
OptionalAndNamedParams(int32 a,
[opt] string b,
[opt] object c) cil managed
{
.param [2] = ""
.param [3] = "https://www.xianfen.Net"
// ...
}
public void OptionalAndNamedParams(int a,
[Optional, DefaultParameterValue("")] string b,
[Optional, DefaultParameterValue("https://www.xianfen.Net")] object c)
{
Console.WriteLine("a:{0}, b:{1}, c:{2}", a, b, c);
}
OptionalAttribute + DefaultParameterValueAttribute 非 .NET 4.0 新類別,早期供 VB/VC++ 等支援可選參數的語言使用DefaultParameterValue,預設值為型別默認值 (null/0/false)
// 呼叫 t.OptionalAndNamedParams(1) 的 Release 模式 IL
IL_0006: ldloc.0
IL_0007: ldc.i4.1
IL_0008: ldstr "" // 編譯器內嵌預設值 ""
IL_000d: ldstr "https://www.xianfen.Net" // 編譯器內嵌預設值
IL_0012: callvirt instance void Test::OptionalAndNamedParams(int32,string,object)
**編譯器將預設值內嵌到調用端 IL**,而非運行期綁定。若修改庫中方法的預設值,**未重新編譯調用端的程式集將繼續使用舊預設值**,導致行為不一致。
// 原方法
public void OptionalAndNamedParams(int a, string b = "", object c = "url") { }
// 新增多載
public void OptionalAndNamedParams(int a, string b)
=> Console.WriteLine("overload, a:{0}, b:{1}", a, b);
調用 t.OptionalAndNamedParams(1) 時,**優先匹配參數完全吻合的多載**,而非使用可選參數版本。
Nullable<T> 或重載替代可選參數以避免版本陷阱