4

我在字符串中保存方法体。我想动态创建方法。但我不知道,如何设置它的身体。我看到使用 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
4

3 回答 3

7

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

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

在 4.0 中,ExpressionAPI 比 3.5 中的要丰富得多,允许大多数常见的构造而没有CodeDom. 但是不要打折Reflection.Emit——你需要花一点时间来了解ILGenerator并使用堆栈,但这并不像人们想象的那么糟糕。

作为旁注,除非您只想执行一次,否则不要使用Invokefrom 。DynamicMethod更好的方法是使用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();

或使用ExpressionAPI:

var lambda =Expression.Lambda<Func<string>>(Expression.Constant("Hello, world"));
var func = lambda.Compile();
var s = func();
于 2010-06-07T06:14:02.057 回答
2

您需要查看这些命名空间:

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

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

于 2010-06-07T05:17:07.670 回答
1

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

于 2010-06-07T05:15:49.257 回答