Joe*_*ger 5 c# expression-trees system.reflection
在我的一个库中,我有从表达式返回MethodInfo的代码:
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;
}
Run Code Online (Sandbox Code Playgroud)
我有一系列辅助函数来启用如下调用:
public MethodInfo Func<T, R, A1>(Expression<Func<T, Func<A1, R>>> expression)
{
return GetMethod(expression);
}
Run Code Online (Sandbox Code Playgroud)
这将启用以下语法:
var methodInfo = Func<TestClass, bool, string>(x => x.AnInstanceMethodThatTakesAStringAndReturnsABool);
Run Code Online (Sandbox Code Playgroud)
这很好用,直到我最近将库升级到.Net 4.6.1和最新的c#编译器.
在.net的早期版本中,表达式将采用以下形式:
{x => Convert(CreateDelegate(System.Func`2[System.String, System.Boolean], x, Boolean AnInstanceMethodThatTakesAStringAndReturnsABool(System.String)))}
Run Code Online (Sandbox Code Playgroud)
因此,我的代码会将methodInfoExpression作为methodCallExpression的最后一个参数.
现在,在.Net 4.6.1(最新的c#编译器)中,编译器似乎正在生成一个不同形式的表达式:
{x => Convert(Boolean AnInstanceMethodThatTakesAStringAndReturnsABool(System.String).CreateDelegate(System.Func`2[System.String, System.Boolean], x))}
Run Code Online (Sandbox Code Playgroud)
我当前的代码中断,因为最后一个参数不是ConstantExpression.看着它 - 轻松修复,只需改为
var methodInfoExpression = (ConstantExpression)methodCallExpression.Object;
Run Code Online (Sandbox Code Playgroud)
显然,GetMethod函数非常脆弱,并且可能会改变编译器生成表达式的方式.我很好奇这个更改的原因以及我如何重构GetMethod,以便它对编译器生成的表达式树更具弹性.
| 归档时间: |
|
| 查看次数: |
97 次 |
| 最近记录: |