2008-09-19 26 views
5

比方說,我們有以下方法聲明:VB.NET可選參數如何工作'底層'?他們是否符合CLS?

Public Function MyMethod(ByVal param1 As Integer, _ 
    Optional ByVal param2 As Integer = 0, _ 
    Optional ByVal param3 As Integer = 1) As Integer 

    Return param1 + param2 + param3 
End Function 

如何VB.NET使可選參數的CLR的範圍內工作?是可選參數CLS兼容?

回答

7

有趣的是,這是反編譯的C#代碼,通過反射器獲得。

public int MyMethod(int param1, 
        [Optional, DefaultParameterValue(0)] int param2, 
        [Optional, DefaultParameterValue(1)] int param3) 
{ 
    return ((param1 + param2) + param3); 
} 

注意可選和DefaultParameterValue屬性。嘗試將它們放在C#方法中。您會發現您仍然需要將值傳遞給該方法。然而,在VB代碼中,它變成了Default!這就是說,我個人從來沒有使用默認即使在VB代碼。這感覺就像一個黑客。方法重載對我來說是訣竅。

雖然在處理Excel Interop時,默認會有所幫助,這是在C#中直接使用的屁股中的一個痛處。

+0

這很酷......我沒有把它一直回到C#反射器;猜我應該有! – 2008-09-19 18:22:46

6

與流行的看法相反,可選參數似乎確實符合CLS標準。 (但是,我的主要檢查是將所有的CLSCompliant屬性標記爲程序集,類和方法,設置爲True。)

那麼這在MSIL中看起來如何?

.method public static int32 MyMethod(int32 param1, 
             [opt] int32 param2, 
             [opt] int32 param3) cil managed 
{ 
    .custom instance void [mscorlib]System.CLSCompliantAttribute::.ctor(bool) = (01 00 01 00 00) 
    .param [2] = int32(0x00000000) 
    .param [3] = int32(0x00000001) 
    // Code size  11 (0xb) 
    .maxstack 2 
    .locals init ([0] int32 MyMethod) 
    IL_0000: nop 
    IL_0001: ldarg.0 
    IL_0002: ldarg.1 
    IL_0003: add.ovf 
    IL_0004: ldarg.2 
    IL_0005: add.ovf 
    IL_0006: stloc.0 
    IL_0007: br.s  IL_0009 
    IL_0009: ldloc.0 
    IL_000a: ret 
} // end of method Module1::MyMethod 

注意參數上的[opt]標記 - MSIL本身支持此標記,沒有任何黑客入侵。 (不同於MSIL對VB的Static關鍵字的支持,這是另一個話題。)

那麼,爲什麼不在C#中呢?我不能回答這個問題,除了我猜測這可能是假設缺乏需求。我自己的偏好一直是指定參數,即使它們是可選的 - 對我而言,代碼看起來更清晰並且更易於閱讀。 (如果省略了參數,我經常首先查找與可見簽名相匹配的超載 - 它只是在我找不到可以選擇參數的參數之後才發現的參數。)