我希望从lambda表达式中获取方法名称,我知道可以这样做:
GetName(() => MethodA());
我的问题是如果MethodA
接受任何args,你必须提供它们只是为了满足编译器关于表达式(毕竟,它怎么知道你并没有真正执行它?)< / p>
我希望能够做到:
GetName(() => MethodA);
有没有办法做到这一点?
注意:这不是重复,这是处理Method Group
而不是实际的&#34;调用&#34;一种方法。
答案 0 :(得分:3)
当然可以。例如,如果您使用GetName方法将Expression<Func<Action>>
作为参数,则可以将() => MethodA
传递给它,只要MethodA可以转换为与Action
相同的委托签名即可。
void Main()
{
Expression<Func<Action>> x = () => Foo;
Expression<Func<Func<int>>> y = () => Foo2;
var xName = ((MethodInfo)((ConstantExpression)((MethodCallExpression)((UnaryExpression)x.Body).Operand).Object).Value).Name;
}
void Foo(){}
int Foo2(){return 0;}
您可以编写GetName方法来检查给定的表达式,并从中提取出方法组的名称。但是,你应该记住两件事。
出于这个原因,我不得不想象你最好使用 涉及方法调用表达式的更传统的方法。
答案 1 :(得分:1)
对于void
- 返回无参数方法的情况,GetName
的签名可能如下所示:
string GetName(Expression<Func<Action>> methodExpression)
存在问题Action
,为了使其适用于具有其他签名的方法,您需要为其他委托类型添加大量重载。
对此的解决方案是使GetName
通用并让用户指定委托类型:
string GetName<T>(Expression<Func<T>> methodExpression)
…
GetName<Action>(() => MethodA)
这种方法的问题是T
可以是任何类型,而不仅仅是代理,因此很容易调用此版本的GetName
错误,特别是因为类型推断,GetName(() => MethodB())
经常会编译(具体来说,当MethodB
返回某些内容时)。
类型约束无法帮助您,您无法撰写where T : Delegate
。