Come funzionano i parametri opzionali di VB.NET "Roba da smanettoni"? Sono conformi a CLS?

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

  •  01-07-2019
  •  | 
  •  

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?

È stato utile?

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.)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top