Gibt es eine Entsprechung für das C # 4-Schlüsselwort 'dynamic', wenn typsicheres VB.NET verwendet wird, dh mit Option Strict On
?
c#
vb.net
dynamic
option-strict
jeroenh
quelle
quelle
dynamic
in C # hätte. Jeder, der zustimmt oder nicht zustimmt, kann hierAntworten:
Das Äquivalent ist Object in VB.NET, aber mit
Option Strict Off
. MitOption Strict On
gibt es kein Äquivalent. Anders ausgedrückt, das dynamische Schlüsselwort bringt esOption Strict Off
C # äquivalente Funktionen.quelle
In VB.NET war immer die "dynamische" Funktion integriert, die ursprünglich als späte Bindung bezeichnet wurde. Diese Syntax wurde für immer unterstützt:
Dim obj = new SomeComClass() obj.DoSomething()
Arbeitete an Code, der in .NET und COM implementiert ist, wobei letzterer die häufigste Verwendung ist. Das dynamische Schlüsselwort in C # gab ihm die gleiche Fähigkeit. Es wurde in VB.NET Version 10 geändert, verwendet jetzt jedoch auch das DLR. Dies unterstützt Sprachimplementierungen wie Python und Ruby bei der dynamischen Bindung.
Die Syntax ist genau die gleiche. Verwenden Sie das Schlüsselwort Dim ohne As. Sie müssen jedoch Option Strict Off verwenden. Option Infer On kann diesen Schlag etwas mildern. Es zeigt, dass C # mit einem bestimmten Schlüsselwort zur Signalisierung der dynamischen Bindung ein ziemlich guter Schachzug war. Afaik alle Anfragen dazu auch in VB.NET wurden bisher berücksichtigt, aber nicht geplant.
Wenn Sie Option Strict On bevorzugen, ist die Verwendung des Schlüsselworts Partial Class, mit dem Sie einen Teil des Codes in eine andere Quelldatei verschieben können, wahrscheinlich der effektivste Ansatz.
quelle
app
wird als Typ abgeleitetObject
, so ist es nicht möglich, verwenden Sie das Excel - Application - Objektapp
. Wenn ich zum Beispiel ersetze,app.Calculate
wo Sie es haben, wirdREM etc...
es nicht kompiliert. Ich denke, das ist das Problem, nach dem Jeroen fragt. Der Compiler sagtError 1 Option Strict On disallows late binding.
dynamic
. Jeder, der stark zustimmt oder nicht zustimmt, kann hierOption
Anweisungen am Anfang der Datei überschreiben .Dies zeigt, was Basic über VB sagt, das nicht die gleiche Granularität wie C # aufweist. Ich habe diesen Code in C #, der mithilfe der Reflektion eine Methode zur Laufzeit dynamisch aufruft:
var listResult = tgtObj.GetType().GetMethod("GetSomeData").Invoke(tgtObj, null);
Der Grund, warum ich das mache, ist, dass "GetSomeData" eine von mehreren Methoden sein kann, die jeweils unterschiedliche Daten erhalten. Welche Methode hier aufgerufen werden soll, hängt von einem Zeichenfolgenparameter ab, der zur Laufzeit an dieses Objekt übergeben wird. Daher variiert der Wert von "GetSomeData" zur Laufzeit.
Die Signatur von "GetSomeData" lautet:
public List<SomeResultSetClass> GetSomeData()
Jede der aufgerufenen Methoden gibt eine Art
List<T>
Objekt zurück. Als Nächstes sende ich das listResult-Objekt an eine generische Methode namens Export, die folgendermaßen aussieht:void Export<T>(List<T> exportList, string filePath, byte fileType) where T: class;
Hier stoßen wir auf ein Problem. Invoke gibt ein Objekt vom Typ System.Object zurück. Natürlich
List<T>
ist a auch ein System.Object, aber die offenbarte Schnittstelle ist die System.Object-Schnittstelle, nicht die IList-Schnittstelle. Wenn ich versuche, die Exportmethode auszuführen, gilt Folgendes:myExportObj.Export(listResult, parms.filePath, parms.fileType);
Der Code kann nicht kompiliert werden. Der Fehler ist:
The type arguments for method '...Export<T>...' cannot be inferred from the usage. Try specifying the type arguments explicitly.
Nein Danke!! Das Problem ist, dass der Compiler die IList-Metadaten nicht finden kann, da er die System.Object-Schnittstelle betrachtet. Jetzt können Sie eine neue erstellen
List<T>
, ihr zuweisen(List<Whatever>) listResult
, aber das macht den Zweck des dynamischen Aufrufs in erster Linie zunichte.Das Update ist zu ändern
var
zudynamic
:dynamic listResult = tgtObj.GetType().GetMethod("GetSomeData").Invoke(tgtObj, null);
Da Dynamic die statische Typprüfung zur Kompilierungszeit umgeht, wird kein Kompilierungsfehler angezeigt. Wenn das dynamische Objekt an die Exportmethode übergeben wird, prüft das DLR (Dynamic Language Runtime), ob es das Objekt implizit umwandeln kann, um die Anforderungen der Methodensignatur zu erfüllen. Was es natürlich kann.
Ok, so funktionieren die Dinge in C #. Bei VB sieht die Linie folgendermaßen aus:
Dim listResult = tgtObj.GetType().GetMethod("GetSomeData").Invoke(tgtObj, Nothing)
Mit Option Strict On stört diese Zeile den Compiler wie erwartet. Wenn es ausgeschaltet ist, funktioniert es gut. Mit anderen Worten, in VB muss ich die Typprüfung für das gesamte Modul deaktivieren, das die Zeile enthält. Es gibt keine feinere Granularität als diese.
quelle
Sie können Option Infer On und Option Strict Off aktivieren und trotzdem etwas sehr Nahes haben.
quelle
Es gibt genügend Möglichkeiten, Methoden und Eigenschaften mit spät bindenden COM-Objekten zu verarbeiten und safe (
Option Strict On
) einzugeben . Dies bei Verwendung der Methoden Microsoft.VisualBasic.Interaction.CallByName und System.Type.InvokeMember. (Oder erstellen Sie eine separate "partielle" Datei, wo sichOption Strict
befindetOff
).Die Behandlung von Ereignissen mit verspäteter Bindung von VB.NET ist jedoch nicht so einfach wie beim dynamischen Typ in C #. Sie können den "Hack" dafür in Dynamic Events in VB.NET überprüfen .
quelle
Das Äquivalent des dynamischen Schlüsselworts c # in Vb.Net mit der Option strict on ist als NuGet-Paket vorhanden: Dynamitey.
Nach dem Installationspaket Dynamitey kann man Vb.Net-Code wie folgt schreiben:
Option Strict On : Option Infer On : Option Explicit On Imports Dynamitey Module Module1 Public Sub Main() Dim o = Nothing o = "1234567890" Console.WriteLine(Dynamic.InvokeMember(o, "Substring", 5)) ' writes 67890 End Sub End Module
Oder das etwas besser lesbare:
Option Strict On : Option Infer On : Option Explicit On Imports Dynamitey Module Module1 <Extension()> Public Function Substring(self As Object, offset As Integer) As String Return CType(Dynamic.InvokeMember(self, "Substring", offset), String) End Function Public Sub Main() Dim o = Nothing o = "1234567890" Console.WriteLine(Substring(o, 5)) ' writes 67890 End Sub End Module
Getestet mit VS2017 und .net Framework 4.7.2.
quelle
Ja, ExpandoObject.
quelle
Option Strict On
. Ihre Antwort funktioniert nur mitOption Strict Off
Beachten Sie, dass Sie auch bei aktivierter Option Strict z. B. ein ExpandoObject verwenden können, um auf Eigenschaften wie Folgendes zuzugreifen:
Dim doc = JsonConvert.DeserializeObject(Of ExpandoObject)("{""name"":""Bob""}") Dim lookup as IDictionary(Of String, Object) = doc lookup("name") ' Bob
quelle