Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/271.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

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# 使用Lambda表达式选择类方法名称_C#_Linq_Reflection_Lambda - Fatal编程技术网

C# 使用Lambda表达式选择类方法名称

C# 使用Lambda表达式选择类方法名称,c#,linq,reflection,lambda,C#,Linq,Reflection,Lambda,目前在我的代码中,我有这样一个方法: .AddMethod(nameof(IRoleService.GetRoles)) 我要做的是使用lambda表达式选择接口方法,然后在AddMethod中获取方法的名称。 因此,结果将是: .AddMethod<IRoleService>(x=> x.GetRoles) .AddMethod(x=>x.GetRoles) 我试过这个: AddMethod<T>(Expression<Func<T, Actio

目前在我的代码中,我有这样一个方法:

.AddMethod(nameof(IRoleService.GetRoles))
我要做的是使用lambda表达式选择接口方法,然后在AddMethod中获取方法的名称。 因此,结果将是:

.AddMethod<IRoleService>(x=> x.GetRoles)
.AddMethod(x=>x.GetRoles)
我试过这个:

AddMethod<T>(Expression<Func<T, Action>> expression);
AddMethod(表达式);
但问题是有些接口方法有我试图忽略的输入参数,因为我只需要方法名。 如果你能帮我,我会很感激的

亚历克斯

但问题是有些接口方法有输入参数 我试图忽略它

不能忽略输入参数,除非这些参数具有默认值

如果您无法更改代码来为这些方法的输入参数设置默认值,那么您需要自己使用反射来提供默认值,以获取所谓的输入参数并为它们提供一些值。或者,您可以在编译时提供:

// I don't know which parameters accept your methods...
AddMethod<IRoleService>(x => x.GetRoles("arg1", 2));
//我不知道哪些参数接受您的方法。。。
AddMethod(x=>x.GetRoles(“arg1”,2));
奥普说。。。
考虑到我只需要方法名,您是否建议一种干净的方法 在不传递参数的情况下获取名称

这样做没有肮脏或干净的方式。表达式树仍然是有效的代码(即,它应该是可以构建到可执行代码中的代码)


如何生成一个表达式树,在其中访问方法名而不是调用它?或者如果整个方法都有参数,如何访问一个方法来调用它而不带参数?这是有效的C代码吗?答案是

这可以通过对
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;
}
不幸的是,
GetMethodCallName
无法使用所需的
x=>x.GetRoles
语法直接调用,因为没有类型参数来定义
x
是什么。这意味着您需要为
Action
Func
要支持的每个输入参数创建一个
AddMethod
重载:

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);
然后可以调用
AddMethod
,并指定方法的包含类型以及返回和输入类型:

.AddMethod<IRoleService>(x => x.GetRoles);
.AddMethod<IRoleService, TResult>(x => x.GetRoles);
.AddMethod<IRoleService, Arg1, TResult>(x => x.GetRoles);
.AddMethod(x=>x.GetRoles);
.AddMethod(x=>x.GetRoles);
.AddMethod(x=>x.GetRoles);
其中:

  • TResult
    的返回类型。GetRoles
  • Arg1
    .GetRoles

谢谢@Matías Fidemraizer。考虑到我只需要方法名,您是否建议一种不传递参数的干净方法来获取名称?谢谢您的详细描述。谢谢你的帮助。@Alex不客气。嗯,有时候答案是说你的问题没有解决办法……;)这个答案如何解决这个问题?OP说:但问题是有些接口方法有我试图忽略的输入参数,因为我只需要方法名。如果您能帮助我,我将不胜感激。我更新了我的解决方案以适应输入参数。遗憾的是,无法指定输入参数的类型,但至少不需要提供值。新选择的答案如何解决您的问题?它可能与
操作
(无输入参数)一起工作,但如果某个方法具有您在问题中所述的输入参数,会发生什么情况?
.AddMethod<IRoleService>(x => x.GetRoles);
.AddMethod<IRoleService, TResult>(x => x.GetRoles);
.AddMethod<IRoleService, Arg1, TResult>(x => x.GetRoles);