5

Is it possible to write a simple and fast function in C# that will execute arbitrary methods from a string? For example, if I set MyString="MessageBox.Show("Some Message")" and then call ExecuteString(MyString), a message box would pop up with "Some Message" in it.

(I've probably made some sort of error in the above code. I don't yet know C#; I'm trying to evaluate whether it would be appropriate for a specific project.)

1

3 Answers 3

3

You should be able to use this and wrap the code required to run a string into a function.

Essentially what you're doing is wrapping the small bit of C# code in a Program.Mainstyle function, referencing some assemblies for basic functionality (maybe including your own assembly) then run the compiled program in memory.

It's likely a bit of more overhead than you need to simply run one or two lines of code mind you.

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

Sign up to request clarification or add additional context in comments.

3 Comments

Agreed -- the best alternative is really to delegate this kind of work to IronPython or IronRuby, where it's much easier to do.
Yeah it would be better to use lightweight script-based methods for such small amounts of "script code".
If a context is required e.g access to runtime variables and classes in host application from the code string than ironPython or other DLR languages is much better Or if the code string changes often than compile assembly is not a good option anyway as you will creating a assembly for each code string that need evaluation.
3

what you appear to be looking for is CS-Script

Comments

2

Alas, C# is not a dynamic language in that way. You can't really do this easily, and if it's really something you need to do, consider using a .Net language more in line with your needs, like IronPython or IronRuby.

Your best available alternative is to use the CodeDom namespace, as this truly convoluted and heinous example from this forum thread shows:

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});
            }
        }
    }
}

2 Comments

You actually can. I've not only posted how, but also done it myself.
I didn't say it wasn't possible, just that it wasn't easy. I'm not sure that the MSDN example you mention -- which requires over 100 lines to "execute" a single line of code, mind you -- could be considered easy.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.