假设我们有以下方法声明:
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?
答案 0 :(得分:7)
有趣的是,这是通过反射器获得的反编译C#代码。
public int MyMethod(int param1,
[Optional, DefaultParameterValue(0)] int param2,
[Optional, DefaultParameterValue(1)] int param3)
{
return ((param1 + param2) + param3);
}
注意Optional和DefaultParameterValue属性。尝试将它们放在C#方法中。您会发现仍然需要将值传递给方法。但是在VB代码中,它变成了Default!话虽如此,我个人从未在VB代码中使用Default。感觉就像一个黑客。方法重载对我来说很有用。
默认确实有帮助,当处理Excel Interop时,在C#中开箱即用的麻烦很难。
答案 1 :(得分: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#?我无法回答这个问题,除了我猜测可能是缺乏需求。我自己的偏好一直是指定参数,即使它们是可选的 - 对我来说,代码看起来更干净,更容易阅读。 (如果省略了参数,我经常首先查看与可见签名匹配的重载 - 只有在我找不到一个我意识到涉及可选参数的情况之后才会这样做。)