VB.NET可选参数如何在"后台"工作?他们符合CLS吗?
时间:2020-03-06 14:27:06 来源:igfitidea点击:
假设我们有以下方法声明:
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?
解决方案
与普遍看法相反,可选参数确实符合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
请注意,参数-MSIL上的[opt]标记本身就支持此功能,没有任何改动。 (与MSIL对VB的Static关键字的支持不同,后者是另一个主题。)
那么,为什么不是这些在C#中?除了推测可能是需求不足之外,我无法回答。我自己的偏好始终是指定参数,即使它们是可选的-对我来说,代码看起来更简洁并且更易于阅读。 (如果省略了参数,我通常会首先寻找与可见签名匹配的重载-只有在我找不到一个我意识到涉及可选参数的重载之后)。
有趣的是,这是通过反射器获得的反编译的Ccode。
public int MyMethod(int param1, [Optional, DefaultParameterValue(0)] int param2, [Optional, DefaultParameterValue(1)] int param3) { return ((param1 + param2) + param3); }
注意Optional和DefaultParameterValue属性。尝试将它们放入Cmethods中。我们会发现仍然需要将值传递给方法。但是在VB代码中,它变成了Default!话虽这么说,我个人从来没有甚至在VB代码中使用默认值。感觉就像是骇客。方法重载对我有用。
但是,在处理Excel Interop时,默认确实会有所帮助,这对于在C#中直接使用开箱即用来说是很痛苦的。