C#:执行存储在字符串变量中的函数

时间:2010-01-21 05:29:23

标签: c# dynamic-languages

是否可以在C#中编写一个简单快速的函数来执行字符串中的任意方法?例如,如果我设置MyString =“MessageBox.Show(”Some Message“)”然后调用ExecuteString(MyString),则会弹出一个消息框,其中包含“Some Message”。

(我可能在上面的代码中犯了一些错误。我还不知道C#;我正在尝试评估它是否适合特定的项目。)

3 个答案:

答案 0 :(得分:3)

您应该能够使用它并将运行字符串所需的代码包装到函数中。

基本上你正在做的是在Program.Main样式函数中包含一些C#代码,引用一些程序集以获得基本功能(可能包括你自己的程序集),然后在内存中运行已编译的程序。 p>

这可能比你只需要运行一行或两行代码就需要更多的开销。

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

答案 1 :(得分:3)

您正在寻找的是CS-Script

答案 2 :(得分:2)

唉,C#不是那种动态语言。你不能轻易做到这一点,如果它真的是你需要做的事情,可以考虑使用更符合你需求的.Net语言,比如IronPython或IronRuby。

您最好的选择是使用CodeDom命名空间,因为this forum thread中这个真正令人费解和令人发指的例子显示:

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