Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 通过Linq表达式指定MethodInfo的未来证明方法_C#_Linq_Reflection - Fatal编程技术网

C# 通过Linq表达式指定MethodInfo的未来证明方法

C# 通过Linq表达式指定MethodInfo的未来证明方法,c#,linq,reflection,C#,Linq,Reflection,我想要一种通过Linq表达式指定方法的未来证明方法 我正在设计一个允许用户指定方法的API。例如,客户端代码可能如下所示:ApiClass.DoSomethingc=>c.ClientMethod 我的API是强类型的。比如说, public void DoSomething(Expression<Func<TClientClass, Func<TParams, TResult>>> method){ ... } 我的问题:如何正确解析表达式树以获取客户端指

我想要一种通过Linq表达式指定方法的未来证明方法

我正在设计一个允许用户指定方法的API。例如,客户端代码可能如下所示:ApiClass.DoSomethingc=>c.ClientMethod

我的API是强类型的。比如说,

public void DoSomething(Expression<Func<TClientClass, Func<TParams, TResult>>> method){ ... }
我的问题:如何正确解析表达式树以获取客户端指定的MethodInfo

我一直在使用下面的代码,但似乎.NET4.5的4.5版通过生成一个稍微不同的表达式树打破了它。显然,我更希望有一个能适用于C/.NET未来所有版本的东西

与SO的答案类似的现有代码:


此代码在.NET 4.5.1上失败:结果是methodInfoValue为空。

一种可能的解决方案似乎是使用ExpressionVisitor遍历表达式并查找值为MethodInfo、MethodInfo.DeclaringType为正确类的任何ConstantExpression


这似乎在.NET上起作用≤ 4和.NET 4.5。

这是未来的兼容版本吗?我仍然不确定C可能生成的合理表达式树的范围应该是什么。这里有来自Microsoft.NET团队的人吗?我不确定即使是.NET团队也有来自未来的时间旅行者来回答这个问题。撇开尖刻的回应不谈,不要以为你会因为时间流逝而升级到一个更新的框架。如果您的代码是为4.5编写的,那么就为4.5构建它,除非您验证它是否可以在5.0或接下来的任何版本上运行。我真的在寻找这样做的最佳实践,或者像“不要这样做”这样的知情评论,因为.NET保留更改此类特定实现细节的权利。我知道事情会发生变化,但一般来说,做事情的方式越来越不适合未来。这里有一个类似的问题:尽管我仍然好奇一个合理的未来解决方案。你可能想举一个完整的例子来证明这一点。我不能责备它。
private static MethodInfo GetMethodInfo(Expression method)
{
    var lambda = method as LambdaExpression;
    if (lambda == null) throw new ArgumentException("Argument is not a lambda expression (c => c.Thing)");
    var convert = lambda.Body;
    var body = (convert.NodeType == ExpressionType.Convert)
        ? ((UnaryExpression)convert).Operand as MethodCallExpression
        : convert as MethodCallExpression;
    if (body == null) throw new ArgumentException("Argument not in correct form (c => c.Thing)");
    var methodInfoValue = body
        .Arguments.OfType<ConstantExpression>()
        .Where(exp => exp.Type == typeof(MethodInfo))
        .Select(exp => (MethodInfo)exp.Value)
        .FirstOrDefault();
    if (methodInfoValue == null) throw new ArgumentException("Cannot find method name in expression.");
    return methodInfoValue;
}