簡體   English   中英

我如何發出System.Linq.Expression?

[英]How do I Emit a System.Linq.Expression?

我有一些代碼使用System.Linq.ExpressionsExpression.Lambda<Func<>>.Compile()等生成各種Func<>委托。我希望能夠將生成的函數序列化為程序集以便稍后使用采用。 在過去,我已經使用System.Reflection.Emit做了一些事情,但是現在Linq表達式我寧願不再去那條路了。

是否有一種機制可以將已編譯的表達式或某種橋接從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");

(其中fieldfield1field2Type T的屬性, ABType T1的屬性。我可以傳遞<T>任何枚舉來query和返回以及與查詢條件匹配的<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(...)

LambdaExpression有一個CompileToMethod方法,它以MethodBuilder為目標。 使用this和Reflection.Emit,您應該能夠創建一個類並將其寫入程序集。

我不確定你的大局是什么,但純粹看你的第二段,你可以編寫基於表達式的純代碼,構建它,然后使用“Reflection.Emit”語言加載項在Reflector中打開你的程序集。 這段元元素技巧將向您展示動態生成Expression / Lambda代碼所需的Reflection.Emit語句。

-Oisin

我認為沒有辦法做到這一點。 畢竟, Expression可以捕獲任意運行時值,這些值無法序列化到程序集中。

看起來你可以通過調用expr.Compile().Method.GetMethodBody().GetILAsByteArray()來獲取IL作為字節,然后可以將其寫入程序MethodBuilder然后可以寫入文件。 不幸的是,這不起作用 - GetMethodBody()調用失敗,因為委托是動態的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM