針對此問題的探索來源於咱們一般使用的默認參數,相似於ide
void NullTest(String str1, string str2 = "default")
這種形式的代碼常用。開始我猜想是某種語法糖的實現,然而查閱資料後發現和我想的不同。url
url連接http://stackoverflow.com/questions/5497514/what-does-opt-mean-in-msilcode
首先反編譯ci
.method public hidebysig instance void NullTest(string str1, [opt] string str2) cil managed { .param [2] = "default" // 代碼大小 2 (0x2) .maxstack 8 IL_0000: nop IL_0001: ret } // end of method Program::NullTest
由opt和param指令能夠看出這並不是是語法糖而是由metadata支持的功能。事實上這種寫法只是一種簡寫形式get
完整的寫法應該是以下形式string
void NullTest2(String str1, [Optional, DefaultParameterValue("default")]string str2)
反編譯的形式和上面的徹底相同。io
這裏用到了兩個特性標記(OptionalAttribute和DefaultParameterValueAttribute),這兩個特性是clr底層支持,寫在Param table中,結合生成的il代碼,提供了參數約束的能力,相似的還有編譯
不一樣的標記可能會存儲一些數據到元數據中如default,也有可能在編譯中提供功能標記,如in和out。table
此外能夠使用自定義特性,class
[AttributeUsage(AttributeTargets.Parameter)] public class MyTestAttribute : Attribute { }
反編譯以下
[MyTest2] private void NullTest3(String str1, [MyTest]string str2) { } .method private hidebysig instance void NullTest3(string str1, string str2) cil managed { .param [2] .custom instance void NullParatweTest.MyTestAttribute::.ctor() = ( 01 00 00 00 ) // 代碼大小 2 (0x2) .maxstack 8 IL_0000: nop IL_0001: ret } // end of method Program::NullTest3
此時須要在程序中反射使用該特性。