【问题标题】:Future-proof way to specify a MethodInfo via a Linq Expression通过 Linq 表达式指定 MethodInfo 的面向未来的方法
【发布时间】:2014-05-29 17:59:08
【问题描述】:

我想要一种通过 Linq 表达式指定方法的面向未来的方式。

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

我的 API 是强类型的。例如,

public void DoSomething(Expression<Func<TClientClass, Func<TParams, TResult>>> method){ ... }

我的问题:我如何正确地解析表达式树以获得客户端指定的 MethodInfo?

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

现有代码(类似于对 SO Extract method name from expression tree? 的回答):

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

(此代码在 .NET 4.5.1 上失败:以空 methodInfoValue 结尾。)

【问题讨论】:

  • 这里有类似的问题:stackoverflow.com/questions/12166785/… 虽然我仍然对一个合理的面向未来的解决方案感到好奇。
  • 你可能想提出“完整的例子”来证明这一点。我无法复制它。

标签: c# linq reflection


【解决方案1】:

一种可能的解决方案似乎是使用ExpressionVisitor 遍历Expression 并查找任何ConstantExpression,其值为MethodInfo,其MethodInfo.DeclaringType 属于正确的类...

这似乎适用于 .NET ≤ 4 和 .NET 4.5。

【讨论】:

  • 未来兼容吗?我仍然不确定 C# 可能生成的合理表达式树的范围是什么。这里有 Microsoft.NET 团队的成员吗?
  • 我不确定 .Net 团队是否有来自未来的时间旅行者来回答这个问题。撇开刻薄的反应不谈,不要仅仅因为时间过去就假设你会升级到更新的框架。如果您的代码是为 4.5 编写的,则为 4.5 构建它,除非您确认它可以在 5.0 或接下来的任何版本上运行。
  • 我真的在寻找做这种事情的最佳实践,或者(知情的)cmets,比如“不要这样做,因为 .NET 保留更改某某的权利具体实施细则”。我知道事情会发生变化,但通常有越来越少的面向未来/可移植的做事方式。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-05-16
  • 2014-09-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-27
  • 1970-01-01
相关资源
最近更新 更多