5

假设我们有以下方法声明:

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?

4

2 回答 2

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 代码中,它变成了默认值!话虽如此,我个人从未在 VB 代码中使用过 Default 。感觉就像一个黑客。方法重载对我有用。

但是,在处理 Excel 互操作时,默认确实有帮助,在 C# 中直接使用开箱即用是一件很痛苦的事情。

于 2008-09-19T18:10:05.357 回答
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# 中呢?我无法回答这个问题,除了我猜测这可能是假定的需求不足。我自己的偏好一直是指定参数,即使它们是可选的——对我来说,代码看起来更干净,更容易阅读。(如果有省略的参数,我通常会首先寻找与可见签名匹配的重载——只有在我找不到一个之后,我才意识到涉及可选参数。)

于 2008-09-19T17:55:42.273 回答