Как VB.NET Дополнительные параметры работают "Под капотом"?Соответствуют ли они CLS?
Вопрос
Допустим, у нас есть следующее объявление метода:
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?
Решение
Интересно, что это декомпилированный код на C #, полученный с помощью reflector.
public int MyMethod(int param1,
[Optional, DefaultParameterValue(0)] int param2,
[Optional, DefaultParameterValue(1)] int param3)
{
return ((param1 + param2) + param3);
}
Обратите внимание на необязательные атрибуты и DefaultParameterValue.Попробуйте поместить их в методы C #.Вы обнаружите, что от вас по-прежнему требуется передавать значения методу.Однако в коде VB он превратился в Default!При этом лично я никогда не использовал Default даже в коде VB.Это похоже на взлом.Перегрузка метода делает свое дело за меня.
Однако Default действительно помогает при работе с взаимодействием Excel, которое является занозой в заднице при использовании прямо из коробки в C #.
Другие советы
Вопреки распространенному мнению, необязательные параметры, по-видимому, соответствуют 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 #?Я не могу ответить на этот вопрос, кроме моего предположения, что это может быть предполагаемое отсутствие спроса.Моим собственным предпочтением всегда было указывать параметры, даже если они были необязательными - на мой взгляд, код выглядит чище и его легче читать.(Если есть пропущенные параметры, я часто сначала ищу перегрузку, соответствующую видимой сигнатуре - только после того, как мне не удается ее найти, я понимаю, что задействованы необязательные параметры.)