Как преобразовать выражение LambdaExpression в типизированное выражение <Func <T, T >>

Я динамически создаю запросы linq для nHibernate.

Из-за зависимостей, я хотел бы бросить/получить типизированное выражение позже, но до сих пор я был неудачным.

Это не работает (бросок должен произойти в другом месте):

var funcType = typeof (Func<,>).MakeGenericType(entityType, typeof (bool));
var typedExpression =  (Func<T, bool>)Expression.Lambda(funcType, itemPredicate, parameter); //Fails

Это работает:

var typedExpression = Expression.Lambda<Func<T, bool>>(itemPredicate, parameter);

Можно ли получить "инкапсулированное" типизированное выражение из выражения LambdaExpression?

Ответы

Ответ 1

var typedExpression =
    (Func<T, bool>)Expression.Lambda(funcType, itemPredicate, parameter); //Fails

Это неудивительно, поскольку вы должны Compile a LambdaExpression, чтобы получить фактический делегат, который может быть вызван (что является тем, что Func<T, bool> is).

Итак, это сработает, но я не уверен, что это то, что вам нужно:

// This is no longer an expression and cannot be used with IQueryable
var myDelegate =
    (Func<T, bool>)
    Expression.Lambda(funcType, itemPredicate, parameter).Compile();

Если вы не хотите компилировать выражение, а вместо этого перемещать дерево выражений, то вместо этого вместо него следует использовать Expression<Func<T, bool>>:

var typedExpression = (Expression<Func<T, bool>>) 
                      Expression.Lambda(funcType, itemPredicate, parameter);