Как VB.NET Дополнительные параметры работают "Под капотом"?Соответствуют ли они CLS?

StackOverflow https://stackoverflow.com/questions/104068

  •  01-07-2019
  •  | 
  •  

Вопрос

Допустим, у нас есть следующее объявление метода:

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 #?Я не могу ответить на этот вопрос, кроме моего предположения, что это может быть предполагаемое отсутствие спроса.Моим собственным предпочтением всегда было указывать параметры, даже если они были необязательными - на мой взгляд, код выглядит чище и его легче читать.(Если есть пропущенные параметры, я часто сначала ищу перегрузку, соответствующую видимой сигнатуре - только после того, как мне не удается ее найти, я понимаю, что задействованы необязательные параметры.)

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top