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

Joe*_*oeS 5 c# dynamic-languages

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

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

Joh*_*lla 2

遗憾的是,C# 并不是这样一种动态语言。您确实无法轻松做到这一点,如果这确实是您需要做的事情,请考虑使用更符合您需求的 .Net 语言,例如 IronPython 或 IronRuby。

最好的替代方案是使用 CodeDom 命名空间,正如该论坛主题中这个真正令人费解且令人发指的示例所示:

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});
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)