C#默認參數原理探究

原由

寫這一篇的原由是想要經過新增默認參數來代替之前的方法,結果發現儘管在調用時寫起來同樣,實際上也沒有被當作一樣的方法,兩個方法大體以下:html

// 先前的方法-刪除
private static string TestMethod(string first)
{
    return first;
}

// 新增的同名方法
private static string TestMethod(string first, string second = "2")
{
    return second;
}

上述兩種方法均可以經過 TestMethod("1"); 調用,因此最開始誤覺得兩個方法的調用是等價的,可是實際使用中經過DLL引用的方式會提示找不到方法,這裏就出現了問題。編程

首先咱們能夠進行一個嘗試,會發現這兩個方法能夠同時存在,仍是上面的例子,這時再經過 TestMethod("1"); 調用會發現返回的結果是「1」,也就是第一個沒有默認參數的方法工具

到這裏爲止,暫時還不太清楚原理,可是能夠感受到調用時程序中的寫法多是區別的,這時候咱們能夠再深刻一點,經過中間語言IL(Intermediate Language)的角度去看一下命令行

ILSpy

藉助一個簡單的例子,先用經常使用的反編譯工具看一下code

static void Main(string[] args)
{
    Console.WriteLine(TestMethod("1"));
    Console.ReadKey();

    TestMethodWithDefaultParam(string.Empty);
}

private static string TestMethod(string first)
{
    return first;
}

private static string TestMethod(string first, string second = "2")
{
    return second;
}

private static void TestMethodWithDefaultParam(string first, string second = "2")
{

}

把編譯的好的程序放到ILSpy裏面反編譯看下htm

重點對比看下 TestMethodWithDefaultParam 這個方法的調用,能夠發現雖然咱們沒有傳入第二個參數,可是因爲默認參數的存在,編譯器自動幫咱們補上了一個參數,而 TestMethod 方法則明顯是調用第一個沒有默認參數的,有默認參數的 TestMethod 方法被忽略了blog

ildasm

經過ILSpy咱們簡單的看到調用時兩個方法的區別,可是默認參數的實現狀況咱們還不是很清楚,因此能夠再經過VisualStudio自帶的IL反彙編程序ildasm看一下,使用VS的命令行工具輸入 ildasm 打開程序,而後打開咱們的控制檯程序的exe文件get

經過這個目錄咱們能夠明確的看到,兩個TestMethod方法的參數形式,默認參數的方式只是讓咱們在調用的時候能夠省略參數,而在程序中這個方法仍然具備這個參數,當兩個同名的方法一塊兒存在是就至關於方法的重載,調用時傳入對應的參數即調用對應的方法編譯器

這時咱們打開有默認參數的方法,能夠看到在IL的形式下,默認參數前面有個[opt]的標識,表明着Optional,即「可選的」,這是C#的一個特性標籤——OptionalAttribute,經過OptionalAttribute和DefaultParameterValueAttribute這兩個特性也就實現了C#的默認參數,這方面已經有相關的博文,能夠參考談談C# 4.0新特性「缺省參數」的實現string

相關文章
相關標籤/搜索