Ich kann eval("something()");
den Code dynamisch in JavaScript ausführen. Gibt es eine Möglichkeit für mich, dasselbe in C # zu tun?
Ein Beispiel für das, was ich versuche, ist: Ich habe eine ganzzahlige Variable (sagen wir i
) und ich habe mehrere Eigenschaften mit den Namen: "Property1", "Property2", "Property3" usw. Nun möchte ich einige Operationen ausführen auf der Eigenschaft "Property i " abhängig vom Wert von i
.
Dies ist mit Javascript wirklich einfach. Gibt es eine Möglichkeit, dies mit C # zu tun?
c#
reflection
properties
c#-2.0
Adhip Gupta
quelle
quelle
Antworten:
Leider ist C # keine solche dynamische Sprache.
Sie können jedoch eine C # -Quellcodedatei mit Klasse und allem erstellen, diese über den CodeDom-Anbieter für C # ausführen, zu einer Assembly kompilieren und dann ausführen.
Dieser Forumsbeitrag auf MSDN enthält eine Antwort mit einem Beispielcode auf der Seite:
Erstellen Sie eine anonyme Methode aus einer Zeichenfolge?
Ich würde kaum sagen, dass dies eine sehr gute Lösung ist, aber es ist trotzdem möglich.
Welche Art von Code erwarten Sie in dieser Zeichenfolge? Wenn es sich um eine kleine Teilmenge gültigen Codes handelt, beispielsweise nur um mathematische Ausdrücke, gibt es möglicherweise andere Alternativen.
Edit : Nun, das lehrt mich, die Fragen zuerst gründlich zu lesen. Ja, Reflexion kann Ihnen hier helfen.
Wenn Sie die Zeichenfolge durch die; Um einzelne Eigenschaften abzurufen, können Sie zunächst den folgenden Code verwenden, um ein PropertyInfo-Objekt für eine bestimmte Eigenschaft für eine Klasse abzurufen, und dann mit diesem Objekt ein bestimmtes Objekt bearbeiten.
Link: PropertyInfo.SetValue-Methode
quelle
GetMethod(methodName)
stattdessen verwenden, die Parameterwerte analysieren und die Methode mithilfe von Reflection aufrufen.Verwenden der Roslyn-Skript-API (weitere Beispiele hier ):
Sie können auch einen beliebigen Code ausführen:
Verweisen Sie auf den Code, der in früheren Läufen generiert wurde:
quelle
Nicht wirklich. Sie können Reflexion verwenden, um das zu erreichen, was Sie wollen, aber es ist nicht annähernd so einfach wie in Javascript. Wenn Sie beispielsweise das private Feld eines Objekts auf etwas setzen möchten, können Sie diese Funktion verwenden:
quelle
Dies ist eine Bewertungsfunktion unter c #. Ich habe es verwendet, um anonyme Funktionen (Lambda-Ausdrücke) aus einer Zeichenfolge zu konvertieren. Quelle: http://www.codeproject.com/KB/cs/evalcscode.aspx
quelle
Ich habe ein Open-Source-Projekt geschrieben, Dynamic Expresso , das Textausdrücke, die mit einer C # -Syntax geschrieben wurden, in Delegaten (oder Ausdrucksbäume) konvertieren kann. Ausdrücke werden analysiert und ohne Kompilierung oder Reflexion in Ausdrucksbäume umgewandelt .
Sie können so etwas schreiben wie:
oder
Meine Arbeit basiert auf dem Artikel von Scott Gu http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx .
quelle
All das würde definitiv funktionieren. Persönlich würde ich für dieses spezielle Problem wahrscheinlich einen etwas anderen Ansatz wählen. Vielleicht so etwas:
Wenn Sie solche Muster verwenden, müssen Sie darauf achten, dass Ihre Daten als Referenz und nicht als Wert gespeichert werden. Mit anderen Worten, tun Sie dies nicht mit Grundelementen. Sie müssen ihre großen aufgeblähten Klassenkollegen verwenden.
Mir wurde klar, dass dies nicht genau die Frage ist, aber die Frage wurde ziemlich gut beantwortet und ich dachte, vielleicht könnte ein alternativer Ansatz helfen.
quelle
Ich weiß es jetzt nicht, wenn Sie unbedingt C # -Anweisungen ausführen möchten, aber Sie können Javascript-Anweisungen bereits in C # 2.0 ausführen. Die Open-Source-Bibliothek Jint ist dazu in der Lage. Es ist ein Javascript-Interpreter für .NET. Übergeben Sie ein Javascript-Programm und es wird in Ihrer Anwendung ausgeführt. Sie können das C # -Objekt sogar als Argumente übergeben und es automatisieren.
Versuchen Sie es auch mit NCalc, wenn Sie nur den Ausdruck Ihrer Eigenschaften auswerten möchten .
quelle
Sie können Reflection verwenden, um die Eigenschaft abzurufen und aufzurufen. Etwas wie das:
Angenommen, das Objekt mit der Eigenschaft heißt "theObject" :)
quelle
Sie können auch einen Webbrowser implementieren und dann eine HTML-Datei laden, die Javascript enthält.
Dann gehen Sie
document.InvokeScript
in diesem Browser zur Methode. Der Rückgabewert der eval-Funktion kann abgefangen und in alles konvertiert werden, was Sie benötigen.Ich habe dies in mehreren Projekten gemacht und es funktioniert perfekt.
Ich hoffe es hilft
quelle
Sie könnten es mit einer Prototypfunktion tun:
und so weiter...
quelle
Verwendet Reflection, um einen datenbindenden Ausdruck zur Laufzeit für ein Objekt zu analysieren und auszuwerten.
DataBinder.Eval-Methode
quelle
Ich habe ein Paket geschrieben, SharpByte.Dynamic , um das dynamische Kompilieren und Ausführen von Code zu vereinfachen. Der Code kann für jedes Kontextobjekt mit Erweiterungsmethoden aufgerufen werden, wie hier näher beschrieben .
Beispielsweise,
gibt 3 zurück;
Gibt die Zeichenfolgendarstellung des Kontextobjekts zurück.
führt diese Anweisungen als Skript usw. aus.
Ausführbare Dateien können einfach mit einer Factory-Methode abgerufen werden, wie im Beispiel hier gezeigt. Sie benötigen lediglich den Quellcode und die Liste aller erwarteten benannten Parameter (Token werden in dreifacher Klammer wie {{{0}} eingebettet). }, um Kollisionen mit string.Format () sowie Lenker-ähnlichen Syntaxen zu vermeiden):
Jedes ausführbare Objekt (Skript oder Ausdruck) ist threadsicher, kann gespeichert und wiederverwendet werden, unterstützt die Protokollierung innerhalb eines Skripts, speichert Zeitinformationen und die letzte Ausnahme, falls diese auftreten usw. Außerdem wird für jedes Objekt eine Copy () -Methode kompiliert, um dies zu ermöglichen Erstellen billiger Kopien, dh Verwenden eines ausführbaren Objekts, das aus einem Skript oder Ausdruck kompiliert wurde, als Vorlage zum Erstellen anderer.
Der Aufwand für die Ausführung eines bereits kompilierten Skripts oder einer Anweisung ist relativ gering und liegt bei bescheidener Hardware deutlich unter einer Mikrosekunde. Bereits kompilierte Skripte und Ausdrücke werden zur Wiederverwendung zwischengespeichert.
quelle
Ich habe versucht, einen Wert eines Struktur- (Klassen-) Mitglieds anhand seines Namens zu ermitteln. Die Struktur war nicht dynamisch. Alle Antworten funktionierten nicht, bis ich es endlich bekam:
Diese Methode gibt den Wert des Mitglieds anhand seines Namens zurück. Es funktioniert mit regulärer Struktur (Klasse).
quelle
Sie können die Heleonix.Reflection- Bibliothek überprüfen . Es bietet Methoden zum dynamischen Abrufen / Setzen / Aufrufen von Mitgliedern, einschließlich verschachtelter Mitglieder. Wenn ein Mitglied klar definiert ist, können Sie einen Getter / Setter (Lambda, der zu einem Delegaten kompiliert wurde) erstellen, der schneller als die Reflektion ist:
Wenn die Anzahl der Eigenschaften nicht unbegrenzt ist, können Sie Setter generieren und zwischenspeichern (Setter sind schneller, da sie kompilierte Delegaten sind):
Setter können vom Typ sein,
Action<object, object>
aber Instanzen können zur Laufzeit unterschiedlich sein, sodass Sie Listen von Setzern erstellen können.quelle
Leider verfügt C # über keine nativen Funktionen, um genau das zu tun, was Sie verlangen.
Mein C # -Eval-Programm ermöglicht jedoch die Auswertung von C # -Code. Es ermöglicht die Auswertung von C # -Code zur Laufzeit und unterstützt viele C # -Anweisungen. Tatsächlich kann dieser Code in jedem .NET-Projekt verwendet werden, ist jedoch auf die Verwendung der C # -Syntax beschränkt. Weitere Informationen finden Sie auf meiner Website http://csharp-eval.com .
quelle
Die richtige Antwort ist, dass Sie das gesamte Ergebnis zwischenspeichern müssen, um die Speichernutzung gering zu halten.
Ein Beispiel würde so aussehen
und fügen Sie es einer Liste hinzu
Speichern Sie die ID und verwenden Sie sie im Code
hoffe das hilft
quelle