C# 如何转换表达式<;Func<;T、 对象>&燃气轮机;表达<;Func<;对象,对象>&燃气轮机;

C# 如何转换表达式<;Func<;T、 对象>&燃气轮机;表达<;Func<;对象,对象>&燃气轮机;,c#,linq,lambda,expression-trees,linq-expressions,C#,Linq,Lambda,Expression Trees,Linq Expressions,有没有办法把表达式转换成表达式?我以前不得不这么做 public static class ExpressionHelper { public static Expression<Func<object,object>> ConvertParameterToObject<T>(this Expression<Func<T,object>> source){ return source.ReplacePa

有没有办法把
表达式
转换成
表达式

我以前不得不这么做

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

    }

}
公共静态类ExpressionHelper{
公共静态表达式转换器ParameterToObject(此表达式源){
返回source.ReplaceParametersWithBase();
}
公共静态表达式ReplaceParameterWithBase(此表达式lambda)
其中T:TBase
{
var param=lambda.Parameters.Single();
返回(表达式)
ParameterRebinder.ReplaceParameters(新字典
{
{param,Expression.Parameter(typeof(TBase),param.Name)}
},lambda.Body);
}
}
公共类参数Rebinder:ExpressionVisitor
{
私有只读字典映射;
公共参数索引(字典映射)
{
this.map=map??新建字典();
}
公共静态表达式替换参数(字典映射、表达式表达式)
{
返回新参数浏览器(map)。访问(exp);
}
受保护的重写表达式VisitParameter(ParameterExpression p)
{
参数表达替换;
if(映射TryGetValue(p,输出替换))
{
p=替换;
}
返回基访问参数(p);
}
}

像这样的东西怎么样:

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
静态表达式转换函数(表达式函数)
{
ParameterExpression p=表达式。参数(typeof(object));
返回表达式.Lambda
(
Expression.Invoke(函数,表达式.Convert(p,typeof(T))),p
);
}
然后你可以这样说:

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
表达式foo=s=>s.Length;
表达式条=转换函数(foo);
var call=bar.Compile();
控制台。写(打电话(“你好”);//印刷品5

铸造
T
成为
对象
?比如
(object)T
我到底应该怎么做?我正在获取
Expression nameSelector
,我需要将该
nameSelector
作为
Expression
传递给另一个函数。要使用您的函数,它会在
返回新参数索引(map)时出错。访问(exp)显示错误消息:未为类型“System.Object”定义属性“System.String NewDescription”。该错误有意义。一旦替换了参数,就无法知道对象是什么类型,因此将不会定义成员。在这种情况下,您可能需要执行一个
Compile()
,像
表达式toObj=x=>stronglyTyped.Compile()((T)x)
一样强制转换和调用。我自己也尝试过回答这个问题,最后得到了相同的解决方案。转换在使用其参数的表达式(如object以外的其他类型)上不会成功。这与
返回x=>函数.Compile()有什么区别吗((T)x)
?这种方法将表达式从
{o=>o.NewDescription}
更改为
{Param_0=>调用(o=>o.NewDescription,Convert(Param_0))}
有没有办法保持相同的表达式?