内联的ILEmit DynamicMethod的内容到前pression树 [英] Inlining contents of an ILEmit DynamicMethod into an expression tree

查看:303
本文介绍了内联的ILEmit DynamicMethod的内容到前pression树的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个生成使用ILEmit一个DynamicMethod的方法,我想内联前pression树中的内容。我需要这样做是为了写EX pression树的组件。

I have a method which generates a DynamicMethod using ILEmit, and I want to inline its contents inside an expression tree. I need to do this in order to write the expression tree to an assembly.

我可以编译DynamicMethod的,并包括到树上,但是这$ P $写入前pression树组装错误如下pvents我:

I can compile the DynamicMethod and include that into the tree, but this prevents me from writing the expression tree to an assembly with the following error:

CompileToMethod不能编译常量BulkUtil + BlitMethod(字节),因为它是一个不平凡的价值,比如一个活动对象。相反,创建一个前pression树可以构造此值。

CompileToMethod cannot compile constant 'BulkUtil+BlitMethod[Byte]' because it is a non-trivial value, such as a live object. Instead, create an expression tree that can construct this value.

由于我产生方法的主体反正,我想我只是内联成树,以便它可以输出。然而,由于该方法会产生不安全code,我不知道如何将其直接转换。

Since I'm generating the body of the method anyways, I figured I'd just inline it into the tree so that it could be output. However, because the method generates unsafe code I don't know how to translate it directly.

有没有办法直接添加IL到前pression树?

Is there a way to directly add IL to an expression tree?

推荐答案

我认为,试图内联IL进入前pression树是不正确的做法,因为这将意味着你必须知道如何IL从ex pression生成的样子(至少在一定程度)。另外,据我所知,有没有简单的方法来做到这一点。

I think that trying to inline the IL into the expression tree is not the right approach, because it would mean you would have to know how the IL generated from the expression looks like (at least to some degree). Also, as far as I know, there is no simple way to do that.

你可以做的反而是在生成的汇编创建您的IL方法作为一个正常的 MethodBuilder (即不是 DynamicMethod的),然后调用来自EX pression的方法。

What you could do instead is to create your IL method as a normal MethodBuilder in the generated assembly (i.e. not DynamicMethod) and then call that method from the expression.

在code,有一个非常简单的IL和EX pression,可能看起来是这样的:

The code, with a very simple IL and expression, could look something like this:

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");

看来,一个防爆pression 不能叫 MethodBuilder 直接,这意味着两个方法必须在单独的类型,以及包含该方法的IL的类型,必须首先创建

It seems that an Expression can't call MethodBuilder directly, which means that the two methods have to be in separate types and that the type that contains the IL method has to be created first.

这篇关于内联的ILEmit DynamicMethod的内容到前pression树的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆