Редактировать Я думаю, что могу попросить лучше (в этом случае вообще не нужен код). Итак, вопрос в целом заключается в следующем: как использовать дерево выражений для построения вызова общего метода (Select<TEntity,TResult>
в моем случае), когда TResult
создан во время выполнения? Игнорируйте весь код и текст ниже, это была непонятная версия вопроса, оставив его не путать тех, кто ответил.Дерево выражений для перечислимого. Выберите
Мне нужен пример построения дерева выражений для вызова «Выбрать». Проблема в том, что я не знаю тип результата во время компиляции (он может быть определен пользователем через некоторый графический интерфейс во время выполнения). Вот код, как я пытаюсь сделать это (помните, что я не могу использовать дженерики)
class Pet {
public int Id { get; set; }
public string Name { get; set; }
}
Используя этот класс в Main:
List<Pet> list = new List<Pet>();
Expression eList = Expression.Constant(list);
ParameterExpression pe = Expression.Parameter(typeof(Pet), "p");
MethodInfo method = typeof(Program).GetMethod("CreateObject", BindingFlags.Static | BindingFlags.NonPublic);
var properties = typeof(Pet).GetProperties().Where(pi => pi.Name == "Name"); //will be defined by user
Expression selectorBody = Expression.Call(method, Expression.Constant(properties));
Expression selector = Expression.Lambda(selectorBody, pe);
Expression res = Expression.Call(typeof(Enumerable), "Select", new[] { typeof(Pet), CreateType(properties) }, eList, selector);
То, что я пытаюсь сделать создает тип во время выполнения с использованием Reflection.Emit (метод «CreateType» в коде выше, он используется в некоторых моих проектах и отлично выглядит) и каким-то образом передает его для вызова «Выбрать», но я получаю исключение:
Нет универсального метода «Выбрать» по типу «System.Linq.Enumerab le 'совместим с аргументами и аргументами поставляемого типа.
Любые предложения?
Обновление моя настоящая проблема заключается в создании дерева выражений для вызова «Join» для типов времени выполнения, что является более сложным, поэтому я решил спросить о «Select», потому что у меня такое же исключение в последнем line (Expression.Call (...))
Upd2 включил мои вспомогательные методы и отредактировал основной код, однако это не основная проблема.
static Type CreateType(IEnumerable<PropertyInfo> properties) {
TypeBuilder typeBuilder = CreateTypeBuilder("ResultDynamicAssembly", "ResultModule", "ResultType");
foreach (PropertyInfo propertyInfo in properties) {
CreateAutoImplementedProperty(typeBuilder, propertyInfo.Name, propertyInfo.PropertyType);
}
return typeBuilder.CreateType();
}
static object CreateObject(IEnumerable<PropertyInfo> properties) {
Type type = CreateType(properties);
return Activator.CreateInstance(type);
}
Можете ли вы опубликовать свой код? Если дерево выражений, которое вы строите, является сложным, почти невозможно спрогнозировать, что может быть неправильным. –