Como VB.NET Opcional Parâmetros de trabalho 'sob a capa'? Eles são compatíveis com CLS?

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

  •  01-07-2019
  •  | 
  •  

Pergunta

Vamos dizer que temos a seguinte declaração método:

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

Como o VB.NET fazer os parâmetros opcionais trabalhar dentro dos limites do CLR? São parâmetros opcionais CLS-Compliant?

Foi útil?

Solução

Curiosamente, este é o código C # decompiled, obtido via refletor.

public int MyMethod(int param1, 
                   [Optional, DefaultParameterValue(0)] int param2, 
                   [Optional, DefaultParameterValue(1)] int param3)
{
    return ((param1 + param2) + param3);
}

Observe o opcional e DefaultParameterValue atributos. Tente colocá-los em métodos C #. Você vai descobrir que você ainda são obrigados a passar valores para o método. Em VB código no entanto, a sua transformado em padrão! Dito isto, eu, pessoalmente, nunca use padrão, mesmo em código VB. Ela se sente como um hack. Sobrecarga de método faz o truque para mim.

Padrão não ajuda no entanto, quando se lida com o Excel Interop, que é uma dor na bunda para usar em linha reta da caixa em C #.

Outras dicas

Ao contrário da crença popular, os parâmetros opcionais não parece ser compatível com CLS. (No entanto, o meu cheque principal para isso foi para marcar a montagem, classe e método de todos com o atributo CLSCompliant, definida como True.)

Então, o que faz este olhar como em 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

Observe os [opt] marcações sobre os parâmetros - MSIL suporta isso nativamente, sem quaisquer cortes. (Ao contrário de suporte de MSIL para palavra-chave estática do VB, que é outro assunto completamente.)

Então, porque não são estes em C #? Eu não posso responder que, além de minha especulação de que poderia ser uma presumida falta de demanda. Minha preferência sempre foi o de especificar os parâmetros, mesmo se eles eram opcionais - para mim, o código parece mais limpo e é mais fácil de ler. (Se não são omitidos parâmetros, muitas vezes eu olhar primeiro para uma sobrecarga que corresponde à assinatura visível. - É só depois de eu não conseguir encontrar um que eu percebo que os parâmetros opcionais estão envolvidos)

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top