C#默認參數原理探究


起因

寫這一篇的起因是想要通過新增默認參數來代替以前的方法,結果發現盡管在調用時寫起來一樣,實際上也沒有被當做同樣的方法,兩個方法大致如下:

// 先前的方法-刪除
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

借助一個簡單的例子,先用常用的反編譯工具看一下

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里面反編譯看下

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

ildasm

通過ILSpy我們簡單的看到調用時兩個方法的區別,但是默認參數的實現情況我們還不是很清楚,所以可以再通過VisualStudio自帶的IL反匯編程序ildasm看一下,使用VS的命令行工具輸入 ildasm 打開程序,然后打開我們的控制台程序的exe文件

通過這個目錄我們可以明確的看到,兩個TestMethod方法的參數形式,默認參數的方式只是讓我們在調用的時候可以省略參數,而在程序中這個方法仍然具有這個參數,當兩個同名的方法一起存在是就相當於方法的重載,調用時傳入對應的參數即調用對應的方法

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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM