我将方法体保存在字符串中。我想动态创建方法。但我不知道,如何设置它的 body 。我看到使用 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
最佳答案
听起来您想要的是“编译器即服务”。这不在 MS .NET 4.0 中,但可能在以后的版本中。不过,它已经在 Mono 中了。在此之前,可用的选项是:
- 使用
CSharpCodeProvider
,但您必须通过反射将其作为方法加载(并为其创建委托(delegate)) - 使用
CodeDom
- 使用
Reflection.Emit
- 使用
表达式
在 4.0 中,Expression
API 比 3.5 中的要丰富得多,允许大多数常见的构造而无需 CodeDom
的痛苦。但不要小看 Reflection.Emit
- 了解 ILGenerator
和使用堆栈需要一些时间,但它并不像人们倾向于的那么糟糕想想。
作为旁注,不要使用 DynamicMethod
中的 Invoke
,除非您只想执行一次。更好的方法是使用 CreateDelegate
,然后存储(并重新使用)该委托(delegate):
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();
关于c# - 有什么简单的方法可以在 C# 中创建方法并动态设置其主体吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2987198/