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))}
有没有办法保持相同的表达式?