У меня есть некоторый код, который генерирует различный Func<>
делегаты, использующие System.Linq.Expressions
и Expression.Lambda<Func<>>.Compile()
и т.д. Я хотел бы иметь возможность сериализировать сгенерированные функции в блок для более позднего использования. В прошлом я сделал некоторый материал с Системой. Отражение. Испустите, но теперь, когда Выражения Linq я не пошел бы тем путем снова.
Есть ли механизм для сериализации скомпилированного выражения или своего рода моста от Expressions
пространство имен к Emit
пространство имен?
Править
Некоторый фон для контекста: Я работаю над механизмом запроса (главным образом для моего собственного наставления и удовольствия). Учитывая SQL-оператор я хотел бы проанализировать и преобразовать его в лямбду, функционируют и затем сериализируют его к диску на потом (и повторенное выполнение).
В псевдо коде я к этой точке:
Func<IEnumerable<T>, IEnumerable<T1>> query = Query.Parse<T, T1>("Select field AS A, field1 AS B from T where T.field2 > 5");
(где поле, field1 и field2 является свойствами Типа T и A и B, свойства Типа 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(...)
Я не уверен, какова ваша общая картина, но глядя только на второй абзац, вы можете написать код на основе чистого выражения, построить его, а затем откройте свою сборку в Reflector с помощью языковой надстройки Reflection.Emit. Этот кусок мета-мета-уловки покажет вам операторы Reflection.Emit, необходимые для динамической генерации вашего кода Expression / Lambda.
-Oisin
Я не думаю, что есть способ сделать это. В конце концов, выражение Expression
может захватывать произвольные значения времени выполнения, которые нельзя сериализовать в сборку.
Казалось бы, это можно обойти, вызвав expr.Compile (). Method.GetMethodBody (). GetILAsByteArray ()
, чтобы получить IL в байтах, которые затем можно записать в MethodBuilder
в сборке, которую затем можно записать в файл. К сожалению, это не сработает - вызов GetMethodBody ()
завершается неудачно, потому что делегат является динамическим.