C# 为什么不同版本的.net(或编译器)会为同一个表达式生成不同的表达式树
在我的一个库中,我有从表达式返回MethodInfo的代码:C# 为什么不同版本的.net(或编译器)会为同一个表达式生成不同的表达式树,c#,expression-trees,system.reflection,C#,Expression Trees,System.reflection,在我的一个库中,我有从表达式返回MethodInfo的代码: public MethodInfo GetMethod(Expression expression) { var lambdaExpression = (LambdaExpression)expression; var unaryExpression = (UnaryExpression)lambdaExpression.Body; var methodCallExpression = (MethodCallE
public MethodInfo GetMethod(Expression expression)
{
var lambdaExpression = (LambdaExpression)expression;
var unaryExpression = (UnaryExpression)lambdaExpression.Body;
var methodCallExpression = (MethodCallExpression)unaryExpression.Operand;
var methodInfoExpression = (ConstantExpression)methodCallExpression.Arguments.Last();
return (MethodInfo)methodInfoExpression.Value;
}
我有一系列帮助函数来启用如下调用:
public MethodInfo Func<T, R, A1>(Expression<Func<T, Func<A1, R>>> expression)
{
return GetMethod(expression);
}
因此,我的代码将methodInfoExpression作为methodCallExpression的最后一个参数
现在,在.Net 4.6.1(最新的c#编译器)中,编译器似乎正在生成一个不同形式的表达式:
{x => Convert(Boolean AnInstanceMethodThatTakesAStringAndReturnsABool(System.String).CreateDelegate(System.Func`2[System.String, System.Boolean], x))}
我当前的代码中断,因为最后一个参数不是常量表达式。看看它-很容易修复,只需更改为
var methodInfoExpression = (ConstantExpression)methodCallExpression.Object;
显然,GetMethod函数非常脆弱,编译器生成表达式的方式会发生变化。我很想知道更改的原因,以及如何重构GetMethod,使其对编译器生成的表达式树更具弹性
我很好奇改变的原因
从.NET 4.5开始,有两种方法可以从MethodInfo
生成委托:
MethodInfo
上的实例方法,以及Delegate.CreateDelegate
静态方法GetMethod
,使它对编译器生成的表达式树更有弹性
您可以使用,并以这种方式查找方法信息。您应该发布在提供示例时编译的示例代码。如果你想帮助你更有效地编写这个方法,你应该描述它需要做什么,而不是仅仅展示它的非工作版本。非常有用。谢谢
{x => Convert(Boolean AnInstanceMethodThatTakesAStringAndReturnsABool(System.String).CreateDelegate(System.Func`2[System.String, System.Boolean], x))}
var methodInfoExpression = (ConstantExpression)methodCallExpression.Object;