【问题标题】:Is any simple way to create method and set its body dynamically in C#?有什么简单的方法可以在 C# 中创建方法并动态设置其主体吗?
【发布时间】:2011-02-28 13:18:38
【问题描述】:

我在字符串中保存方法体。我想动态创建方法。但我不知道,如何设置它的身体。我看到使用 CodeDom 的方式非常乏味。我看到使用 Emit 和 OpCodes。有什么方法可以使用字符串变量中的现成代码吗?

string method_body = "return \"Hello, world!\";"; //there is method body
DynamicMethod dm = new System.Reflection.Emit.DynamicMethod("My_method",
                 typeof(string), new Type[] { }); //any way to create method dynamically
//any way to set body
string result = (string)dm.Invoke(...); //I need write result in variable

【问题讨论】:

    标签: c# reflection methods dynamic codedom


    【解决方案1】:

    听起来你想要的是“编译器即服务”。这不在 MS .NET 4.0 中,但可能在以后的版本中。不过,它已经在 Mono 中了。在此之前,可用的选项是:

    • 使用CSharpCodeProvider,但您必须通过反射将其作为方法加载(并为其创建委托)
    • 使用CodeDom
    • 使用Reflection.Emit
    • 使用Expression

    在 4.0 中,Expression API 比 3.5 中的要丰富得多,允许大多数常见的构造而没有 CodeDom 的痛苦。但不要忽视Reflection.Emit - 了解ILGenerator 并使用堆栈需要一点时间,但它并没有人们想象的那么糟糕。

    作为旁注,不要使用来自DynamicMethodInvoke,除非您只想执行一次。更好的方法是使用CreateDelegate,然后存储(并重复使用)该委托:

    var dm = new System.Reflection.Emit.DynamicMethod("My_method",
        typeof(string), null);
    var il = dm.GetILGenerator();
    il.Emit(OpCodes.Ldstr, "Hello, world!");
    il.Emit(OpCodes.Ret);
    Func<string> func = (Func<string>)dm.CreateDelegate(typeof(Func<string>));
    var s = func();
    

    或者使用Expression API:

    var lambda =Expression.Lambda<Func<string>>(Expression.Constant("Hello, world"));
    var func = lambda.Compile();
    var s = func();
    

    【讨论】:

      【解决方案2】:

      你需要看看这些命名空间:

      System.Reflection;
      System.CodeDom.Compiler;
      Microsoft.CSharp;
      

      这可能会让你开始:http://www.west-wind.com/presentations/dynamicCode/DynamicCode.htm

      【讨论】:

      • 哦,谢谢!文章中有动态编译的现成类,你参考一下。写 wwScripting lo_script = new wwScripting("CSharp"); lo_script.lSaveSourceCode = true; lo_script.AddAssembly("mscorlib.dll");字符串结果 = (string)lo_script.ExecuteCode(method_body, new object[] { .../*params*/...});非常方便。
      • 这种方法可行,但只有在您绝对信任那里的任何输入代码时才应使用该方法。如果某些最终用户(或者,可能是一些可下载的内容)具有运行代码的能力,那么您应该非常小心。仅供参考,所以它不会在路上咬你。
      【解决方案3】:

      将其保存到 .CS 文件中并即时编译和执行。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-06-20
        • 2017-05-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-09-18
        相关资源
        最近更新 更多