How Do VB.NET Optionale Parameter Arbeit ‚Unter der Haube‘? Sind sie CLS-kompatibel?
Frage
Lassen Sie uns sagen, dass wir die folgende Methode Erklärung haben:
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 macht VB.NET die optionalen Parameter innerhalb der Grenzen der CLR arbeiten? Sind optionale Parameter CLS-konform?
Lösung
Interessanterweise ist dies der dekompilierten C # Code über Reflektor erhalten.
public int MyMethod(int param1,
[Optional, DefaultParameterValue(0)] int param2,
[Optional, DefaultParameterValue(1)] int param3)
{
return ((param1 + param2) + param3);
}
Beachten Sie die optionale und DefaultParameterValue Attribute. Versuchen Sie, sie in C # Methoden setzen. Sie werden feststellen, dass Sie immer noch Werte an die Methode übergeben erforderlich. In VB-Code jedoch seine in Standard geworden! Davon abgesehen, habe ich persönlich nie Standard verwenden, auch in VB-Code. Es fühlt sich an wie ein Hack. Verfahren Überlastung funktioniert der Trick für mich.
Standard tut zwar helfen, wenn sie mit dem Excel Interop tun hat, die ein Schmerz im Arsch ist gerade zu verwenden, aus der Box in C #.
Andere Tipps
Im Gegensatz zur landläufigen Meinung, optionale Parameter erscheinen CLS-kompatibel zu sein. (Allerdings meine primäre Check hierfür war die Montage, Klasse und Methode, um alle mit dem CLSCompliant Attribut zu markieren, auf True gesetzt.)
So was sieht das wie in 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
Beachten Sie die [opt] Markierungen auf den Parameter - MSIL unterstützt diese nativ, ohne Hacks. (Im Gegensatz zu MSIL Unterstützung für statische Keyword-VB, die ein anderes Thema insgesamt ist.)
Also, warum ist diese nicht in C #? Das kann ich nicht, anders als meine Spekulation beantworten, dass es vielleicht ein mutmaßlich fehlende Nachfrage sein. Meine eigene Präferenz ist immer die Parameter angeben, auch wenn sie optional waren - mir, der Code sieht sauberer und leichter zu lesen. (Falls Parameter weggelassen werden, ich sehe oft zunächst für eine Überladung, die die sichtbare Signatur übereinstimmt - es ist nur, nachdem ich nicht, einen zu finden, dass ich erkennen, dass optionale Parameter beteiligt sind.)