如何转换Expression <func <t,object =“”>&gt;表达式<func <object,object =“”>&gt; </func <object,> </func <t,>

时间:2011-05-13 09:32:18

标签: c# linq lambda expression-trees linq-expressions

有没有办法将Expression<Func<T, object>>转换为Expression<Func<object, object>>

2 个答案:

答案 0 :(得分:1)

我以前必须这样做......

public static class ExpressionHelper {
    public static Expression<Func<object,object>> ConvertParameterToObject<T>(this Expression<Func<T,object>> source){
             return source.ReplaceParametersWithBase<T,object,object>();
    }

    public static Expression<Func<TBase,TResult>> ReplaceParameterWithBase<T,TResult,TBase>(this Expression<Func<T,TResult>> lambda)
        where T :TBase
    {
        var param = lambda.Parameters.Single();
        return (Expression<Func<TBase,TResult>>)
            ParameterRebinder.ReplaceParameters(new Dictionary<ParameterExpression, ParameterExpression>
                                                {
                                                    { param, Expression.Parameter(typeof (TBase), param.Name) }
                                                }, lambda.Body);
    }
}


public class ParameterRebinder : ExpressionVisitor
{

    private readonly Dictionary<ParameterExpression, ParameterExpression> map;



    public ParameterRebinder(Dictionary<ParameterExpression, ParameterExpression> map)
    {

        this.map = map ?? new Dictionary<ParameterExpression, ParameterExpression>();

    }



    public static Expression ReplaceParameters(Dictionary<ParameterExpression, ParameterExpression> map, Expression exp)
    {

        return new ParameterRebinder(map).Visit(exp);

    }



    protected override Expression VisitParameter(ParameterExpression p)
    {

        ParameterExpression replacement;

        if (map.TryGetValue(p, out replacement))
        {

            p = replacement;

        }

        return base.VisitParameter(p);

    }

}

答案 1 :(得分:1)

这样的事情怎么样:

static Expression<Func<object,object>> ConvertFunction<T>(Expression<Func<T,object>> function)      
{
    ParameterExpression p=Expression.Parameter(typeof(object));

    return Expression.Lambda<Func<object,object>>
    (
        Expression.Invoke(function,Expression.Convert(p,typeof(T))), p
    );
}

然后你可以这样说:

Expression<Func<string,object>> foo=s=>s.Length;
Expression<Func<object,object>> bar=ConvertFunction(foo);

var call=bar.Compile();
Console.Write(call("hello")) ; // Prints 5