Come funzionano i parametri opzionali di VB.NET "Roba da smanettoni"? Sono conformi a CLS?
Domanda
Diciamo che abbiamo la seguente dichiarazione del metodo:
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
In che modo VB.NET fa funzionare i parametri opzionali all'interno dei confini del CLR? I parametri opzionali sono conformi a CLS?
Soluzione
È interessante notare che questo è il codice C # decompilato, ottenuto tramite reflector.
public int MyMethod(int param1,
[Optional, DefaultParameterValue(0)] int param2,
[Optional, DefaultParameterValue(1)] int param3)
{
return ((param1 + param2) + param3);
}
Nota gli attributi Opzionale e DefaultParameterValue. Prova a metterli nei metodi C #. Scoprirai che devi ancora passare i valori al metodo. Nel codice VB, tuttavia, è diventato Default! Detto questo, personalmente non ho mai usato Default nemmeno nel codice VB. Sembra un trucco. Il metodo di overload fa il trucco per me.
L'impostazione predefinita aiuta tuttavia, quando si ha a che fare con l'interoperabilità di Excel, il che è una seccatura da usare subito in C #.
Altri suggerimenti
Contrariamente alla credenza popolare, i parametri opzionali sembrano conformi a CLS. (Tuttavia, il mio controllo principale per questo era di contrassegnare l'assembly, la classe e il metodo tutti con l'attributo CLSCompliant, impostato su True.)
Che aspetto ha 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
Nota i segni [opt] sui parametri - MSIL supporta questo in modo nativo, senza alcun hack. (A differenza del supporto di MSIL per la parola chiave statica di VB, che è un altro argomento del tutto.)
Quindi, perché non sono presenti in C #? Non posso rispondere, a parte la mia ipotesi che potrebbe essere una presunta mancanza di domanda. La mia preferenza è sempre stata quella di specificare i parametri, anche se erano facoltativi: per me il codice sembra più pulito ed è più facile da leggere. (Se ci sono parametri omessi, cerco spesso prima un sovraccarico che corrisponda alla firma visibile - solo dopo non riesco a trovarne uno mi rendo conto che sono coinvolti parametri opzionali.)