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