Je peux faire un eval("something()");
pour exécuter le code dynamiquement en JavaScript. Y a-t-il un moyen pour moi de faire la même chose en C #?
Un exemple de ce que j'essaie de faire est: J'ai une variable entière (disons i
) et j'ai plusieurs propriétés par les noms: "Propriété1", "Propriété2", "Propriété3", etc. Maintenant, je veux effectuer quelques opérations sur la propriété "Property i " en fonction de la valeur de i
.
C'est vraiment simple avec Javascript. Existe-t-il un moyen de le faire avec C #?
c#
reflection
properties
c#-2.0
Adhip Gupta
la source
la source
Réponses:
Malheureusement, C # n'est pas un langage dynamique comme ça.
Ce que vous pouvez faire, cependant, est de créer un fichier de code source C #, plein de classe et de tout, et de l'exécuter via le fournisseur CodeDom pour C # et de le compiler dans un assembly, puis de l'exécuter.
Ce message de forum sur MSDN contient une réponse avec un exemple de code en bas de la page:
créer une méthode anonyme à partir d'une chaîne?
Je dirais à peine que c'est une très bonne solution, mais c'est possible de toute façon.
À quel type de code allez-vous vous attendre dans cette chaîne? S'il s'agit d'un sous-ensemble mineur de code valide, par exemple simplement des expressions mathématiques, il se peut que d'autres alternatives existent.
Edit : Eh bien, cela m'apprend à lire attentivement les questions d'abord. Oui, la réflexion pourrait vous aider ici.
Si vous divisez la chaîne par le; Tout d'abord, pour obtenir des propriétés individuelles, vous pouvez utiliser le code suivant pour obtenir un objet PropertyInfo pour une propriété particulière d'une classe, puis utiliser cet objet pour manipuler un objet particulier.
Link: PropertyInfo.SetValue, méthode
la source
GetMethod(methodName)
place, analyser les valeurs des paramètres et appeler la méthode en utilisant la réflexion.Utilisation de l'API de script Roslyn (plus d' exemples ici ):
Vous pouvez également exécuter n'importe quel morceau de code:
Et référencez le code généré lors des exécutions précédentes:
la source
Pas vraiment. Vous pouvez utiliser la réflexion pour réaliser ce que vous voulez, mais ce ne sera pas aussi simple qu'en Javascript. Par exemple, si vous souhaitez définir le champ privé d'un objet sur quelque chose, vous pouvez utiliser cette fonction:
la source
C'est une fonction eval sous c #. Je l'ai utilisé pour convertir des fonctions anonymes (expressions Lambda) à partir d'une chaîne. Source: http://www.codeproject.com/KB/cs/evalcscode.aspx
la source
J'ai écrit un projet open source, Dynamic Expresso , qui peut convertir une expression de texte écrite en utilisant une syntaxe C # en délégués (ou arbre d'expression). Les expressions sont analysées et transformées en arborescences d'expression sans utiliser de compilation ou de réflexion.
Vous pouvez écrire quelque chose comme:
ou
Mon travail est basé sur l'article de Scott Gu http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx .
la source
Tout cela fonctionnerait certainement. Personnellement, pour ce problème particulier, j'adopterais probablement une approche un peu différente. Peut-être quelque chose comme ça:
Lorsque vous utilisez des modèles comme celui-ci, vous devez faire attention à ce que vos données soient stockées par référence et non par valeur. En d'autres termes, ne faites pas cela avec les primitives. Vous devez utiliser leurs grands homologues de classe gonflés.
J'ai réalisé que ce n'était pas exactement la question, mais la question a été assez bien répondue et j'ai pensé qu'une approche alternative pourrait peut-être aider.
la source
Je ne le fais pas maintenant si vous voulez absolument exécuter des instructions C #, mais vous pouvez déjà exécuter des instructions Javascript en C # 2.0. La bibliothèque open-source Jint est capable de le faire. C'est un interpréteur Javascript pour .NET. Passez un programme Javascript et il fonctionnera dans votre application. Vous pouvez même passer un objet C # comme arguments et faire une automatisation dessus.
Aussi, si vous souhaitez simplement évaluer l'expression sur vos propriétés, essayez NCalc .
la source
Vous pouvez utiliser la réflexion pour obtenir la propriété et l'invoquer. Quelque chose comme ça:
Autrement dit, en supposant que l'objet qui a la propriété s'appelle "theObject" :)
la source
Vous pouvez également implémenter un navigateur Web, puis charger un fichier html contenant du javascript.
Ensuite, vous allez pour la
document.InvokeScript
méthode sur ce navigateur. La valeur de retour de la fonction eval peut être capturée et convertie en tout ce dont vous avez besoin.J'ai fait cela dans plusieurs projets et cela fonctionne parfaitement.
J'espère que ça aide
la source
Vous pouvez le faire avec une fonction prototype:
etc...
la source
Utilise la réflexion pour analyser et évaluer une expression de liaison de données par rapport à un objet au moment de l'exécution.
DataBinder.Eval, méthode
la source
J'ai écrit un package, SharpByte.Dynamic , pour simplifier la tâche de compilation et d'exécution du code de manière dynamique. Le code peut être appelé sur n'importe quel objet de contexte en utilisant des méthodes d'extension comme détaillé plus loin ici .
Par exemple,
renvoie 3;
renvoie la représentation sous forme de chaîne de l'objet de contexte;
exécute ces instructions sous forme de script, etc.
Les exécutables peuvent être obtenus facilement à l'aide d'une méthode de fabrique, comme le montre l'exemple ici - tout ce dont vous avez besoin est le code source et la liste de tous les paramètres nommés attendus (les jetons sont incorporés en utilisant une notation à trois crochets, telle que {{{0}}) }, pour éviter les collisions avec string.Format () ainsi que les syntaxes de type Handlebars):
Chaque objet exécutable (script ou expression) est thread-safe, peut être stocké et réutilisé, prend en charge la journalisation à partir d'un script, stocke les informations de synchronisation et la dernière exception si elle est rencontrée, etc. Il existe également une méthode Copy () compilée sur chacun pour permettre créer des copies bon marché, c'est-à-dire utiliser un objet exécutable compilé à partir d'un script ou d'une expression comme modèle pour en créer d'autres.
La surcharge liée à l'exécution d'un script ou d'une instruction déjà compilé est relativement faible, bien en dessous d'une microseconde sur du matériel modeste, et les scripts et expressions déjà compilés sont mis en cache pour être réutilisés.
la source
J'essayais d'obtenir une valeur d'un membre de structure (classe) par son nom. La structure n'était pas dynamique. Toutes les réponses n'ont pas fonctionné jusqu'à ce que je l'ai enfin obtenue:
Cette méthode retournera la valeur du membre par son nom. Cela fonctionne sur une structure régulière (classe).
la source
Vous pouvez consulter la bibliothèque Heleonix.Reflection . Il fournit des méthodes pour obtenir / définir / appeler des membres de manière dynamique, y compris des membres imbriqués, ou si un membre est clairement défini, vous pouvez créer un getter / setter (lambda compilé dans un délégué) qui est plus rapide que la réflexion:
Ou si le nombre de propriétés n'est pas infini, vous pouvez générer des setters et les chacher (les setters sont plus rapides puisqu'ils sont des délégués compilés):
Les setters peuvent être de type
Action<object, object>
mais les instances peuvent être différentes lors de l'exécution, vous pouvez donc créer des listes de setters.la source
Malheureusement, C # n'a pas de fonctionnalités natives pour faire exactement ce que vous demandez.
Cependant, mon programme C # eval permet d'évaluer le code C #. Il permet d'évaluer le code C # au moment de l'exécution et prend en charge de nombreuses instructions C #. En fait, ce code est utilisable dans n'importe quel projet .NET, cependant, il est limité à l'utilisation de la syntaxe C #. Jetez un œil à mon site Web, http://csharp-eval.com , pour plus de détails.
la source
la bonne réponse est que vous devez mettre en cache tous les résultats pour réduire l'utilisation de la mémoire.
un exemple ressemblerait à ceci
et ajoutez-le à une liste
enregistrez l'identifiant et utilisez-le dans le code
J'espère que cela t'aides
la source