![](/img/trans.png)
[英]Given two generic type variables, how do I compile a system.linq.expression tree to multiply them?
[英]How do I Emit a System.Linq.Expression?
我有一些代碼使用System.Linq.Expressions
和Expression.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");
(其中field , field1和field2是Type T的屬性, A和B是Type 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.