给出以下方法签名:
string GetActionName<TController, T1, TResult>(Expression<Func<TController, Func<T1, TResult>>> expression)
如何从以下实现中获取方法名称:
GetActionName<EventsController, int, IEnumerable<EventDto>>(c => c.GetEventsByIdLocation);
GetEventsById
的签名为:
IEnumerable<EventDto> GetEventsByIdLocation(int id)
我目前的尝试给了我例外:
无法将“System.Linq.Expressions.InstanceMethodCallExpressionN”类型的对象强制转换为“System.Linq.Expressions.MemberExpression”。
var convertExpression = (UnaryExpression)expression.Body;
var memberExpression = (MemberExpression)convertExpression.Operand;
return memberExpression.Member.Name;
答案 0 :(得分:5)
主要问题是,在你的通话中,你实际上并没有调用该方法,而是返回它。这导致表达式树包含对名为CreateDelegate
的方法的调用。
一旦我们在methodCallExpression
中有了这个,我们需要提取对象,并读取它的值,这是你的方法。
免责声明:这对我有用,我觉得与你的情况相同。但是,如果它是解决我不知道的更大问题的最佳方法。这似乎相当缓慢。
var unaryExpression = (UnaryExpression)expression.Body;
var methodCallExpression = (MethodCallExpression)unaryExpression.Operand;
var constantExpression = (ContantExpression)methodCallExpression.Object;
var methodInfo = (MethodInfo)constantExpression.Value;
return methodInfo.Name
另一个选择是提供对方法的实际方法调用,如下所示:
GetActionName<EventsController, IEnumerable<EventDto>>(
c => c.GetEventsByIdLocation(0));
这需要您将方法更改为:
string GetActionName<TController, TResult>(
Expression<Func<TController, TResult>> expression)
{
return ((MethodCallExpression)expression.Body).Method.Name;
}
此解决方案可能会更快地执行。虽然我没有做任何基准或任何事情。此外,此选项不会使您只能获取带有一个int参数的方法的名称。