Как преобразовать выражение <Func <T, объект >> в выражение <Func <объект, объект >> - PullRequest
2 голосов
/ 13 мая 2011

Есть ли способ конвертировать Expression<Func<T, object>> в Expression<Func<object, object>>?

Ответы [ 2 ]

1 голос
/ 13 мая 2011

Примерно так:

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
1 голос
/ 13 мая 2011

Я должен был сделать это раньше ...

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);

    }

}
...