c# 參數約束原理

 針對此問題的探索來源於咱們一般使用的默認參數,相似於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

此時須要在程序中反射使用該特性。

相關文章
相關標籤/搜索