16

我有一些代码可以使用等生成各种委托Func<>。我希望能够将生成的函数序列化为程序集以供以后使用。过去我用 System.Reflection.Emit 做了一些事情,但现在 Linq 表达式我不想再走那条路了。System.Linq.ExpressionsExpression.Lambda<Func<>>.Compile()

Expressions是否有一种机制可以序列化已编译的表达式或从命名空间到命名空间的某种桥梁Emit

编辑

背景的一些背景:我正在研究一个查询引擎(主要是为了我自己的启发和享受)。给定一条 SQL 语句,我想将其解析并转换为 lambda 函数,然后将其序列化到磁盘以供以后(并重复执行)。

在伪代码中,我到了这一点:

Func<IEnumerable<T>, IEnumerable<T1>> query = Query.Parse<T, T1>("Select field AS A, field1 AS B from T where T.field2 > 5");

(其中fieldfield1field2T 类型的属性,ABT1 类型的属性。我可以传递<T>toquery和 get 的任何枚举,并且它的枚举<T1>与查询条件匹配。

所以我想query作为一个已经编译的程序集序列化到磁盘,以便以后我可以加载它并评估不同的集合,<T>而无需解析和编译它。我正在描绘以下内容:

AssemblyBuilder builder = new AssemblyBuilder(...);
ModuleBuilder module = builder.DefineDynamicModule(...);
TypeBuilder type = module.DefineType(...);
type.AddMethod(query);  // <--- where this piece does not exist as far as I know
builder.Emit(...)
4

3 回答 3

4

LambdaExpression 有一个以 MethodBuilder 为目标的CompileToMethod方法。使用它和 Reflection.Emit,您应该能够创建一个类并将其写入程序集。

于 2012-12-15T00:18:50.043 回答
3

我不确定你的大局到底是什么,但纯粹看你的第二段,你可以编写纯表达式的代码,构建它,然后使用“Reflection.Emit”语言插件在反射器中打开你的程序集。这个元元技巧将向您展示动态生成表达式/Lambda 代码所需的 Reflection.Emit 语句。

-Oisin

于 2010-02-26T22:24:48.490 回答
3

我不认为有任何方法可以做到这一点。毕竟, anExpression可以捕获任意运行时值,这些值无法序列化为程序集。

似乎您可以通过调用expr.Compile().Method.GetMethodBody().GetILAsByteArray()将 IL 作为字节来解决此问题,然后可以将其写入MethodBuilder程序集中的 a 中,然后您可以将其写入文件。不幸的是,这不起作用——GetMethodBody()调用失败,因为委托是动态的。

于 2010-02-26T23:14:51.460 回答