Expression <Func <在T,bool >>或Expression <Func <TBase,bool >>到Expression <Func <T,bool >>转换器

问题描述

|| 有没有简单的转换方法
Expression<Func<TBase,bool>> 
Expression<Func<T,bool>>
T是从TBase继承的?     

解决方法

        只要T从TBase派生,就可以使用原始表达式的主体和参数直接创建所需类型的表达式。
Expression<Func<object,bool>> x = o => o != null;
Expression<Func<string,bool>> y = Expression.Lambda<Func<string,bool>>(x.Body,x.Parameters);
    ,        您可能需要手动转换。原因是您正在有效地转换为可能的子集。所有
T
均为
TBase
,但并非所有
TBase
均为
T
。 好消息是,您可以使用Expression.Invoke进行此操作,然后将适当的强制转换/转换手动应用于
TBase
(当然会遇到任何类型安全问题)。 编辑:对于造成的误解,我深表歉意。我认为,简单地转换表达式仍然是您最好的选择。它使您能够根据需要处理转换。马克·格雷夫(Marc Gravell)的答案是我见过的最简洁明了的方法。     ,        为此,我用重载VisitLambda和VisitParameter编写了ExpressionVisitor 这里是:
public class ConverterExpressionVisitor<TDest> : ExpressionVisitor
{
    protected override Expression VisitLambda<T>(Expression<T> node)
    {
        var readOnlyCollection = node.Parameters.Select(a => Expression.Parameter(typeof(TDest),a.Name));
        return Expression.Lambda(node.Body,node.Name,readOnlyCollection);
    }

    protected override Expression VisitParameter(ParameterExpression node)
    {
        return Expression.Parameter(typeof(TDest),node.Name);
    }
}

public class A { public string S { get; set; } }
public class B : A { }

static void Main(string[] args)
{
    Expression<Func<A,bool>> ExpForA = a => a.S.StartsWith(\"Foo\");
    Console.WriteLine(ExpForA); // a => a.S.StartsWith(\"Foo\");

    var converter = new ConverterExpressionVisitor<B>();
    Expression<Func<B,bool>> ExpForB = (Expression<Func<B,bool>>)converter.Visit(ExpForA);
    Console.WriteLine(ExpForB); // a => a.S.StartsWith(\"Foo\"); - same as for A but for B
    Console.ReadLine();
}
    

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...