詳解C# 4.0中必選參數與可選參數混合的問題
1.使用示例
class Program
{
static void Main(string[] args)
{
Test t = new Test();
t.OptionalAndNamedParams(1);
t.OptionalAndNamedParams(2, "a");
t.OptionalAndNamedParams(3, c: "b", b: "a");
t.OptionalAndNamedParams(4, c: "http://g.cn");
}
}
class Test
{
// a為必選參數;b,c為可選參數
public void OptionalAndNamedParams(int a, string b = "", object c = "http://xianfen.net")
{
Console.WriteLine("a:{0}, b:{1}, c:{2}", a, b, c);
}
}
運行結果為:
使用中的注意事項:
當必選參數與可選參數在同一個方法中混合使用時,必選參數的聲明應該放在可選參數的前面。
可選參數的初始值必須是一個在編譯期可確定的常量。
可選參數不可用ref,out等修飾符。
如果全部顯式指定參數名(paraName:value),參數的順序可以任意調整。
2.內部實現
ILDASM反編譯一下Test.OptionalAndNamedParams,代碼段為:
.method public hidebysig instance void OptionalAndNamedParams(int32 a, |
可選參數前聲明為OptionalAttribute特性。這是C#4.0的語法糖。
Test.OptionalAndNamedParams方法等價的代碼為:
public void OptionalAndNamedParams(int a, |
如果不用DefaultParameterValueAttribute特性設置默認值,則輸出為:
現在知道了Office開發中Missing的原因了。
OptionalAttribute和DefaultParameterValueAttribute不是FCL的新類,他們把方法的參數聲明為可選方法和指定默認值,以便被支持可選參數和默認參數的語言調用(如VB、VC++等)。
3.調用過程
Main方法中,調用t.OptionalAndNamedParams(1)的IL代碼為(Release模式編譯):
|
可以看到,編譯器先取得可選參數的默認值,然后像常規方法一樣調用,并不是后期綁定,這在程序集版本控制時應加以注意,更新了應用程序中含有可選參數方法的程序集后,可能由于默認值的改變導致程序行為異常。
4.方法重載
可選參數與方法重載時,方法的調用方式一模一樣,到底調用的哪個可以舉個例子:
在上面的Test類添加一個方法,定義為:
{
Console.WriteLine("overload, a:{0}, b:{1}", a, b);
}
輸出結果變成:
可以看出,首先調用參數完全匹配的方法。
【編輯推薦】