¿Cómo funcionan los parámetros opcionales de VB.NET 'bajo el capó'?¿Cumplen con CLS?

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

  •  01-07-2019
  •  | 
  •  

Pregunta

Digamos que tenemos la siguiente declaración de 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

¿Cómo hace VB.NET que los parámetros opcionales funcionen dentro de los límites del CLR?¿Los parámetros opcionales son compatibles con CLS?

¿Fue útil?

Solución

Curiosamente, este es el código C# descompilado, obtenido mediante reflector.

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

Observe los atributos Opcional y DefaultParameterValue.Intente ponerlos en métodos C#.Descubrirá que todavía es necesario pasar valores al método.Sin embargo, en el código VB, ¡se convierte en Predeterminado!Dicho esto, personalmente nunca he usado Default ni siquiera en código VB.Se siente como un truco.La sobrecarga de métodos me funciona.

Sin embargo, el valor predeterminado ayuda cuando se trata de la interoperabilidad de Excel, que es una molestia usar directamente en C#.

Otros consejos

Contrariamente a la creencia popular, los parámetros opcionales parecen cumplir con CLS.(Sin embargo, mi verificación principal para esto fue marcar el ensamblado, la clase y el método con el atributo CLSCompliant, establecido en Verdadero).

Entonces, ¿cómo se ve esto en 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

Tenga en cuenta las marcas [opt] en los parámetros: MSIL admite esto de forma nativa, sin ningún tipo de pirateo.(A diferencia del soporte de MSIL para la palabra clave estática de VB, que es otro tema completamente diferente).

Entonces, ¿por qué no están en C#?No puedo responder a eso, más allá de mi especulación de que podría ser una supuesta falta de demanda.Mi preferencia siempre ha sido especificar los parámetros, incluso si fueran opcionales; para mí, el código parece más limpio y más fácil de leer.(Si hay parámetros omitidos, a menudo busco primero una sobrecarga que coincida con la firma visible; solo después de no encontrar uno me doy cuenta de que hay parámetros opcionales involucrados).

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top