简体   繁体   English

转换表达式 <Func<T, TProperty> &gt;表达 <Func<object, object> &gt;反之亦然

[英]Convert Expression<Func<T, TProperty>> to Expression<Func<object, object>> and vice versa

Is there a way to convert the property selector Expression<Func<T, TProperty>> to Expression<Func<object, object>> and vice versa? 有没有办法将属性选择器Expression<Func<T, TProperty>>Expression<Func<object, object>> ,反之亦然? I already know how to convert to Expression<Func<T, object>> using... 我已经知道如何使用...转换为Expression<Func<T, object>>

Expression<Func<T, TProperty>> oldExp;
Expression.Lambda<Func<T, object>>(Expression.Convert(oldExp.Body, typeof(object)), oldExp.Parameters);

... but I need to effectively cast both, the argument and the result of the function, not just eg replace them with a ExpressionVisitor because they need to be casted back later. ...但我需要有效地转换函数的参数和结果,而不仅仅是用ExpressionVisitor替换它们,因为它们需要稍后再生。

You were correct that you need to use an ExpressionVisitor and ExpressionConvert. 你是正确的,你需要使用ExpressionVisitor和ExpressionConvert。

Here are the two methods that you asked for (as well as some support methods): 以下是您要求的两种方法(以及一些支持方法):

public Expression<Func<object, object>> ConvertToObject<TParm, TReturn>(Expression<Func<TParm, TReturn>> input)
{
    var parm = Expression.Parameter(typeof(object));
    var castParm = Expression.Convert(parm, typeof(TParm));
    var body = ReplaceExpression(input.Body, input.Parameters[0], castParm);
    body = Expression.Convert(body, typeof(object));
    return Expression.Lambda<Func<object, object>>(body, parm);
}

public Expression<Func<TParm, TReturn>> ConvertBack<TParm, TReturn>(Expression<Func<object, object>> input)
{
    var parm = Expression.Parameter(typeof(TParm));
    var castParm = Expression.Convert(parm, typeof(object));
    var body = ReplaceExpression(input.Body, input.Parameters[0], castParm);
    body = Expression.Convert(body, typeof(TReturn));
    return Expression.Lambda<Func<TParm, TReturn>>(body, parm);
}

Expression ReplaceExpression(Expression body, Expression source, Expression dest)
{
    var replacer = new ExpressionReplacer(source, dest);
    return replacer.Visit(body);
}

public class ExpressionReplacer : ExpressionVisitor
{
    Expression _source;
    Expression _dest;

    public ExpressionReplacer(Expression source, Expression dest)
    {
        _source = source;
        _dest = dest;
    }

    public override Expression Visit(Expression node)
    {
        if (node == _source)
            return _dest;

        return base.Visit(node);
    }
}

Sample usage: 样品用法:

Expression<Func<Customer, string>> expression = c => c.Name;
var convertedExpression = ConvertToObject<Customer, string>(expression);
var backExpression = ConvertBack<Customer, string>(convertedExpression);

Of course we can replace the original two methods with one method with more type parameters: 当然,我们可以用一个带有更多类型参数的方法替换原来的两个方法:

public Expression<Func<TTargetParm, TTargetReturn>> ConvertGeneric<TParm, TReturn, TTargetParm, TTargetReturn>(Expression<Func<TParm, TReturn>> input)
{
    var parm = Expression.Parameter(typeof(TTargetParm));
    var castParm = Expression.Convert(parm, typeof(TParm));
    var body = ReplaceExpression(input.Body, input.Parameters[0], castParm);
    body = Expression.Convert(body, typeof(TTargetReturn));
    return Expression.Lambda<Func<TTargetParm, TTargetReturn>>(body, parm);
}

Sample usage: 样品用法:

Expression<Func<Customer, string>> expression = c => c.Name;
var convertedExpression = ConvertGeneric<Customer, string, object, object>(expression);
var backExpression = ConvertGeneric<object, object, Customer, string>(convertedExpression);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何转换表达式 <Func<T, TProperty> &gt;表达 <Func<T, TNewProperty> &gt; - How to convert Expression<Func<T, TProperty>> to Expression<Func<T, TNewProperty>> 表达 <Func<TModel,TProperty> &gt;作为对象初始化的属性? - Expression<Func<TModel,TProperty>> as Property for object initialization? 转换功能 <T, TProperty> 表达 <Func<T, Property> &gt; - Convert Func<T, TProperty> to Expression<Func<T, Property>> 表达列表 <Func<T, TProperty> &gt; - List of Expression<Func<T, TProperty>> 转换表达式 <Func<T, object> &gt;表达 <Func<object> &gt; - Convert Expression<Func<T, object>> to Expression<Func<object>> 将Func分配给表达式,反之亦然 - Assigning a Func to an Expression and vice versa 如何转换Expression Func <T, object[]> 到Func <T, object> - Howto convert Expression Func<T, object[]> to Func<T, object> 转换表达式 <Func<XClass, object> &gt;表达 <Func<YClass, object> &gt; - Convert Expression<Func<XClass, object>> to Expression<Func<YClass, object>> PropertyInfo到Expression <Func<TModel, TProperty> &gt; - PropertyInfo to Expression<Func<TModel, TProperty>> 无法从表达式转换 <Func<T1, T2> &gt;`到`Expression <Func<object, object> &gt;` - Cannot convert from `Expression<Func<T1, T2>>` to `Expression<Func<object, object>>`
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM