【发布时间】: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