2008-09-19 15 views
5

Supongamos que tenemos la siguiente declaración de método:¿Cómo funcionan los parámetros opcionales de VB.NET 'Under the hood'? ¿Son CLS-obedientes?

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 se asegura VB.NET los parámetros opcionales de trabajo dentro de los confines del CLR? ¿Son los parámetros opcionales CLS-obedientes?

Respuesta

7

Curiosamente, este es el C decompilado código, obtenido a través del reflector.

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

Observe los atributos Opcionales y DefaultParameterValue. Intenta ponerlos en métodos C#. Descubrirá que todavía está obligado a pasar valores al método. ¡Sin embargo, en el código VB, se convirtió en Default! Dicho esto, personalmente nunca he usado el valor predeterminado incluso en el código VB. Se siente como un truco. La sobrecarga de métodos me funciona.

El valor predeterminado sí ayuda, cuando se trata de la Interoperación de Excel, que es un dolor en el culo para usar directamente de la caja en C#.

+0

Eso es muy bueno ... No volví a tomar C# en Reflector; ¡Supongo que debería haberlo hecho! –

+0

No creo que los valores opcionales sean iguales a la sobrecarga debido al valor predeterminado que tiene que dar a los parámetros opcionales. puedes fingir con sobrecarga, pero no es completamente lo mismo. EN MI HUMILDE OPINIÓN. Solo los uso a veces. – chrissie1

6

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

¿Qué aspecto tiene 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 [opcione] marcas en los parámetros - MSIL admite esto de forma nativa, sin ningún tipo de corte. (A diferencia del soporte de MSIL para la palabra clave estática de VB, que es otro tema en total).

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

Cuestiones relacionadas