【问题标题】:How Do VB.NET Optional Parameters work 'Under the hood'? Are they CLS-Compliant?VB.NET 可选参数如何“在幕后”工作?它们是否符合 CLS 标准?
【发布时间】:2010-09-11 08:52:35
【问题描述】:

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

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?

【问题讨论】:

    标签: .net vb.net clr cil


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

      有趣的是,这是反编译的 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# 中直接使用开箱即用是一件很痛苦的事情。

      【讨论】:

      • 这太酷了……我并没有把它一直带回到Reflector中的C#;猜我应该有!
      • 我不认为可选值与重载相同,因为您必须为可选参数提供默认值。您可以通过重载来伪造它,但它并不完全相同。恕我直言。我只是偶尔使用它们。
      猜你喜欢
      • 2011-07-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多