是否可以将某些返回类型的lambda表达式转换为更具体类型的等效表达式?

时间:2017-05-06 00:04:20

标签: c# lambda expression-trees

public class Entity
{
    public int A { get; set; }
    public string B { get; set; }
}

Expression<Func<Entity,object>> expr = x => x.A;
Expression<Func<Entity,int>> exprAtRuntime = x => x.A;

Expression<Func<Entity,object>> expr2 = x => x.B;
Expression<Func<Entity,string>> expr2AtRuntime = x => x.B;

如何在运行时使用expr并将其转换为expr2的类型?

同样,我需要为属性B执行相同的操作。我需要接受类型为Expression<Func<Entity,object>>的params数组,它表示访问对象的不同属性,因此它们都需要具有实体类型和通用返回对象类型(如answered in this precursor question)。

但是从那个表达式开始,我需要为params数组的每个元素构造它更强类型的版本(即将Expression<Func<TEntity,object>>转换为特定于被访问的基础属性Expression<Func<TEntity,TProperty>>的类型,使用有关在实体类型上访问的属性类型的信息。如何做到这一点?

1 个答案:

答案 0 :(得分:2)

为此,您可以使用ExpressionVisitor删除Convert(如果存在),然后修复委托类型:

class RemoveConvertVisitor : ExpressionVisitor
{
    protected override Expression VisitUnary(UnaryExpression node) =>
        node.NodeType == ExpressionType.Convert ? node.Operand : base.VisitUnary(node);

    protected override Expression VisitLambda<T>(Expression<T> node) =>
        Expression.Lambda(Visit(node.Body), node.Parameters);
}