5 Stimmen

Wie funktionieren optionale VB.NET-Parameter "unter der Haube"? Sind sie CLS-kompatibel?

Nehmen wir an, wir haben die folgende Methodendeklaration:

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

Wie funktioniert VB.NET machen die optionalen Parameter innerhalb der Grenzen der CLR arbeiten? Sind optionale Parameter CLS-kompatibel?

7voto

MagicKat Punkte 9409

Interessanterweise ist dies der dekompilierte C#-Code, der über Reflektor erhalten wurde.

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

Beachten Sie die Attribute Optional und DefaultParameterValue. Versuchen Sie, sie in C#-Methoden einzufügen. Sie werden feststellen, dass Sie trotzdem Werte an die Methode übergeben müssen. In VB-Code hingegen wird daraus Default! Davon abgesehen, habe ich persönlich Default noch nie in VB-Code verwendet. Es fühlt sich wie ein Hack an. Methodenüberladung ist für mich der Trick.

Standard hilft aber, wenn es um die Excel-Interop, die ein Schmerz im Arsch zu verwenden, gerade aus der Box in C # ist.

6voto

John Rudy Punkte 36386

Entgegen der landläufigen Meinung scheinen optionale Parameter CLS-konform zu sein. (Allerdings habe ich dies in erster Linie dadurch überprüft, dass ich die Assembly, die Klasse und die Methode mit dem Attribut CLSCompliant markiert habe, das auf True gesetzt ist).

Wie sieht das nun in MSIL aus?

.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

Beachten Sie die [opt]-Markierungen an den Parametern - MSIL unterstützt dies von Haus aus, ohne irgendwelche Hacks. (Im Gegensatz zu MSILs Unterstützung für das VB-Schlüsselwort Static, was ein ganz anderes Thema ist).

Warum also sind diese nicht in C#? Darauf kann ich keine Antwort geben, außer meiner Vermutung, dass es vielleicht an der mangelnden Nachfrage liegt. Ich selbst habe es immer vorgezogen, die Parameter anzugeben, auch wenn sie optional sind - für mich sieht der Code sauberer aus und ist leichter zu lesen. (Wenn Parameter weggelassen werden, suche ich oft zuerst nach einer Überladung, die der sichtbaren Signatur entspricht - erst wenn ich keine finde, wird mir klar, dass es sich um optionale Parameter handelt).

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X