Ale*_*lex 5 c# linq reflection lambda
目前在我的代码中我有一个这样的方法:
.AddMethod(nameof(IRoleService.GetRoles))
Run Code Online (Sandbox Code Playgroud)
我想要做的是使用lambda表达式选择接口方法,然后在AddMethod中获取方法的名称.结果将是:
.AddMethod<IRoleService>(x=> x.GetRoles)
Run Code Online (Sandbox Code Playgroud)
我试过这个:
AddMethod<T>(Expression<Func<T, Action>> expression);
Run Code Online (Sandbox Code Playgroud)
但问题是一些接口方法有输入参数,我试图忽略,因为我只需要方法名称.如果你能帮助我,我将不胜感激.
亚历克斯
这可以通过一些深入研究来实现,LambdaExpression如下所示:
string GetMethodCallName(LambdaExpression expression)
{
var unary = (UnaryExpression)expression.Body;
var methodCall = (MethodCallExpression)unary.Operand;
var constant = (ConstantExpression)methodCall.Object;
var memberInfo = (MemberInfo)constant.Value;
return memberInfo.Name;
}
Run Code Online (Sandbox Code Playgroud)
不幸的是,GetMethodCallName无法使用您想要的语法直接调用x => x.GetRoles,因为没有类型参数来定义x是什么。这意味着您需要AddMethod为您想要支持Action和的每个输入参数创建一个重载Func:
void AddMethod<T>(Expression<Func<T, Action>> expression);
void AddMethod<T, Arg1>(Expression<Func<T, Action<Arg1>>> expression);
void AddMethod<T, Arg1, Arg2>(Expression<Func<T, Action<Arg1, Arg2>>> expression);
void AddMethod<T, TResult>(Expression<Func<T, Func<TResult>>> expression);
void AddMethod<T, Arg1, TResult>(Expression<Func<T, Func<Arg1, TResult>>> expression);
void AddMethod<T, Arg1, Arg2, TResult>(Expression<Func<T, Func<Arg1, Arg2, TResult>>> expression);
Run Code Online (Sandbox Code Playgroud)
然后在每个AddMethod实现中GetMethodCallName使用表达式参数进行调用:
void AddMethod<T, Arg1>(Expression<Func<T, Action<Arg1>>> expression)
{
var methodName = GetMethodCallName(expression);
}
Run Code Online (Sandbox Code Playgroud)
然后您可以调用AddMethod并指定方法的包含类型以及返回和输入类型:
.AddMethod<IRoleService>(x => x.GetRoles);
.AddMethod<IRoleService, TResult>(x => x.GetRoles);
.AddMethod<IRoleService, Arg1, TResult>(x => x.GetRoles);
Run Code Online (Sandbox Code Playgroud)
在哪里:
TResult是返回类型.GetRolesArg1是第一个参数的类型.GetRoles