我有一个使用DynamicMethod生成ILEmit的方法,我想在表达式树中内联它的内容。我需要这样做,以便将表达式树写入程序集。
我可以编译DynamicMethod并将其包含到树中,但这会阻止我将表达式树写入程序集,但有以下错误:
CompileToMethod无法编译常量'BulkUtil+BlitMethodByte‘,因为它是一个重要的值,例如活动对象。相反,创建一个可以构造此值的表达式树。
因为我正在生成方法的主体,所以我想我应该将它内联到树中,这样就可以输出它。但是,由于该方法生成不安全的代码,所以我不知道如何直接翻译它。
有办法直接将IL添加到表达式树中吗?
发布于 2013-11-04 11:10:09
我认为试图将IL内联到表达式树中并不是正确的方法,因为这意味着您必须知道从表达式生成的IL看起来是什么样子(至少在某种程度上是这样)。而且,据我所知,没有简单的方法可以做到这一点。
相反,您可以做的是将IL方法创建为生成程序集中的普通MethodBuilder (即不是DynamicMethod),然后从表达式中调用该方法。
代码具有非常简单的IL和表达式,可以如下所示:
var assembly = AssemblyBuilder.DefineDynamicAssembly(
new AssemblyName("a"), AssemblyBuilderAccess.RunAndSave);
var module = assembly.DefineDynamicModule("a.dll");
var ilType = module.DefineType("IlType");
var ilMethod = ilType.DefineMethod(
"M", MethodAttributes.Public | MethodAttributes.Static,
typeof(int), Type.EmptyTypes);
var il = ilMethod.GetILGenerator();
il.Emit(OpCodes.Ldc_I4, 42);
il.Emit(OpCodes.Ret);
var createdIlType = ilType.CreateType();
var expressionType = module.DefineType("ExpressionType");
var expressionMethod = expressionType.DefineMethod(
"M", MethodAttributes.Public | MethodAttributes.Static,
typeof(int), Type.EmptyTypes);
var lambda = Expression.Lambda<Func<int>>(
Expression.Call(createdIlType.GetMethod("M")));
lambda.CompileToMethod(expressionMethod);
expressionType.CreateType();
assembly.Save("a.dll");Expression似乎不能直接调用MethodBuilder,这意味着这两个方法必须位于不同的类型中,并且必须首先创建包含IL方法的类型。
发布于 2013-11-25 20:16:39
不幸的是,将表达式树写入方法是非常有限的。您只能编写静态方法,它们只能引用已经物化的类或方法。(即没有建筑商)。
在我完全放弃这个想法之前,我尝试了创建"stub“静态和实例方法的方法,该方法将调用具有同名被调用者的所有参数的委托。
例如:
public class MyClass<Proxy>
{
static Func<MyClass,int,float,long,double,object> <Delegate>Foo
public override object Foo(int a,float b,long c,double d){
return MyClass_Proxy.<Delegate>Foo.Invoke(this,a,b,c,d)
}
}这样,由于一切都是物化的,表达式树可以引用所有成员。这是一次可怕的黑客攻击,后来发展成了一个动态代理。这起作用(我甚至可以说很好),直到您来到泛型方法或泛型类方法之后,它才会面目全非。
您可以看看我对这些代理的看法:https://bitbucket.org/mburbea/delegatedproxy/src、ProxiedTypeBuilder和ProxiedMethodBuilder完成了大部分基于类或接口创建代理类的艰苦工作。我的问题表面有点严重,因为我需要我的代理方法调用它们的基本实现的能力(这是大多数丑陋的代码所要做的),我想出了一个合适的方法来处理带有泛型参数的方法。
https://stackoverflow.com/questions/19738860
复制相似问题