5 votes

C# : exécuter une fonction stockée dans une variable de type chaîne de caractères

Est-il possible d'écrire une fonction simple et rapide en C# qui exécutera des méthodes arbitraires à partir d'une chaîne de caractères ? Par exemple, si je définis MyString="MessageBox.Show("Some Message")" et que j'appelle ensuite ExecuteString(MyString), une boîte de message apparaîtra avec "Some Message".

(J'ai probablement fait une erreur dans le code ci-dessus. Je ne connais pas encore le C# ; j'essaie d'évaluer s'il serait approprié pour un projet spécifique).

3voto

Nick Bedford Points 3009

Vous devriez être en mesure de l'utiliser et d'intégrer le code nécessaire à l'exécution d'une chaîne dans une fonction.

En fait, ce que vous faites, c'est envelopper le petit bout de code C# dans un fichier de type Program.Main en faisant référence à certains assemblages pour la fonctionnalité de base (y compris peut-être votre propre assemblage), puis exécutez le programme compilé en mémoire.

C'est probablement un peu plus de frais généraux que ce dont vous avez besoin pour simplement exécuter une ou deux lignes de code.

http://support.microsoft.com/kb/304655

3voto

ehosca Points 590

Ce que vous semblez rechercher est CS-script

2voto

John Feminella Points 116878

Hélas, C# n'est pas un langage dynamique de cette façon. Vous ne pouvez pas vraiment faire cela facilement, et si c'est vraiment quelque chose que vous devez faire, envisagez d'utiliser un langage .Net plus conforme à vos besoins, comme IronPython ou IronRuby.

Votre meilleure alternative est d'utiliser l'espace de noms CodeDom, comme le montre cet exemple vraiment alambiqué et odieux de ce fil du forum montre :

using System;
using System.CodeDom;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Text;
using System.Windows.Forms;

namespace TestApp
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        SampleLib.SampleType test = new SampleLib.SampleType();

        private void button1_Click(object sender, EventArgs e)
        {
            // Dynamically build and call the method
            label1.Text = test.MyText;
        }

        private void button2_Click(object sender, EventArgs e)
        {
            StringBuilder DynamicCode = new StringBuilder();
            DynamicCode.Append("namespace TestDynamic");
            DynamicCode.Append("{");
            DynamicCode.Append("public class DynamicCode");
            DynamicCode.Append("{");
            DynamicCode.Append("public static void EditText(SampleLib.SampleType t)");
            DynamicCode.Append("{");
            DynamicCode.Append("t.MyText = \"Goodbye!\";");
            DynamicCode.Append("}");
            DynamicCode.Append("}");
            DynamicCode.Append("}");

            string CodeString = DynamicCode.ToString();

            System.IO.FileInfo fi = new System.IO.FileInfo(Application.ExecutablePath);
            CodeDomProvider provider = CodeDomProvider.CreateProvider("C#");
            CompilerParameters CompileParams = new CompilerParameters(new string[] { fi.DirectoryName + "\\SampleLib.dll" },
                fi.DirectoryName + "\\Dynamic.dll");
            CompileParams.MainClass = "DynamicCode";
            CompileParams.GenerateExecutable = false;
            //CompileParams.GenerateInMemory = true;
            CompilerResults r = provider.CompileAssemblyFromSource(CompileParams, new string[] {CodeString});
            foreach (CompilerError er in r.Errors)
            {
                Console.WriteLine(er.ErrorText);
            }
        }

        private void button3_Click(object sender, EventArgs e)
        {
            // Dynamically call assembly
            System.IO.FileInfo fi = new System.IO.FileInfo(Application.ExecutablePath);
            Assembly dynAsm = Assembly.LoadFile(fi.DirectoryName + "\\Dynamic.dll");
            if (dynAsm != null)
            {
                object o = dynAsm.CreateInstance("TestDynamic.DynamicCode", true);
                Type t = dynAsm.GetType("TestDynamic.DynamicCode");
                t.GetMethod("EditText").Invoke(o, new object[]{test});
            }
        }
    }
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X