c# - 将 Expression<Func<T1,bool>> 动态转换为 Expression<Func<T2,bool>

标签 c# linq reflection lambda

我找不到从 Expression> 转换为 Expression> 的方法。由于我使用了很多反射,事实上,我真正需要的是一个接受类型参数并执行转换的方法。

public object Convert(Expression<Func<T1,bool>> expr, Type t);

T2 源​​自T1

public class T1 {
     int FamilyId {get; set;}
}

public class T2 : T1 {
     ... other properties
}

我正在基类上定义一个过滤器表达式

Expression<Func<T1,bool>> filter = p => p.FamilyId == [some value]

我想申请一个列表

最佳答案

这是您要找的吗?该方法有两种风格:第一种让您将新的输入类型作为参数传入;第二个允许您将输入类型作为通用参数传递并获得强类型的 LambdaExpression。

    public static LambdaExpression ChangeInputType<T, TResult>(Expression<Func<T, TResult>> expression, Type newInputType)
    {
        if (!typeof(T).IsAssignableFrom(newInputType))
            throw new Exception(string.Format("{0} is not assignable from {1}.", typeof(T), newInputType));
        var beforeParameter = expression.Parameters.Single();
        var afterParameter = Expression.Parameter(newInputType, beforeParameter.Name);
        var visitor = new SubstitutionExpressionVisitor(beforeParameter, afterParameter);
        return Expression.Lambda(visitor.Visit(expression.Body), afterParameter);
    }

    public static Expression<Func<T2, TResult>> ChangeInputType<T1, T2, TResult>(Expression<Func<T1, TResult>> expression)
    {
        if (!typeof(T1).IsAssignableFrom(typeof(T2)))
            throw new Exception(string.Format("{0} is not assignable from {1}.", typeof(T1), typeof(T2)));
        var beforeParameter = expression.Parameters.Single();
        var afterParameter = Expression.Parameter(typeof(T2), beforeParameter.Name);
        var visitor = new SubstitutionExpressionVisitor(beforeParameter, afterParameter);
        return Expression.Lambda<Func<T2, TResult>>(visitor.Visit(expression.Body), afterParameter);
    }

    public class SubstitutionExpressionVisitor : ExpressionVisitor
    {
        private Expression before, after;
        public SubstitutionExpressionVisitor(Expression before, Expression after)
        {
            this.before = before;
            this.after = after;
        }
        public override Expression Visit(Expression node)
        {
            return node == before ? after : base.Visit(node);
        }
    }

关于c# - 将 Expression<Func<T1,bool>> 动态转换为 Expression<Func<T2,bool>,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15212779/

相关文章:

字符串的 C# 排列 n = ((n - 1) + (n - 2))

C# 相当于 Python 的 struct.pack?

c# - EF6 基于子子项的条件

.net - LINQ to SQL - 更新以增加非主键字段 - 线程安全

java - 使用反射获取java注释

c# - 为什么要复制对象?

c# - 不使用派生类中的方法

c# - System.Diagnostics.Process.HasExited 始终返回 true 并且 Process.Exited 事件处理程序始终在进程仍处于打开状态时命中

c# - 在 C# 中的多列上按结构列表分组

c# - 如何创建一个 Action<T> 形成一个通过反射给出的对象方法?