【问题标题】:Get method name from lambda without call无需调用即可从 lambda 获取方法名称
【发布时间】:2014-08-07 14:54:49
【问题描述】:

我希望从 lambda 表达式中获取方法名称,我知道可以这样做:

GetName(() => MethodA());

我的问题是,如果 MethodA 接受任何参数,您必须提供它们只是为了让编译器满意表达式(毕竟,它怎么知道您实际上并没有执行它?)

我希望能够做到:

GetName(() => MethodA);

有没有办法做到这一点?


注意:这不是重复的,这是处理 Method Group 而不是方法的实际“调用”。

【问题讨论】:

  • @Rawling 这不是重复的!该问题涉及对相关方法的调用。
  • 确实,这不是重复的。我投票重新开放它,还剩 4 票,希望不会花太长时间。至于你的问题,恐怕答案是no
  • @LucasTrzesniewski 恐怕它看起来好像不可能,这是一种耻辱。本质上,我使用它来确定一个方法是否在派生类中被覆盖 - 我知道这是一个坏主意,我这样做只是为了玩耍并快速将某些东西组合在一起以便稍后重做。
  • @Clint 我的错,this one 怎么样? (问题看起来很相似,不确定答案是否有帮助。)
  • 您说“我正在寻找从 lambda 表达式中获取方法名称”,但接着说您不想指定一个有效的lambda,因此您似乎在说您希望能够编写:GetName(MethodA);我想我是在问“你怎么还不知道”(即,如果 MethodA 是一个方法组而不是一个代表,你怎么能“掌握”或传递一个,如果它是一个代表,你已经可以GetName(delegate)) - 我认为缺少一些信息。

标签: c# lambda expression-trees


【解决方案1】:

当然。例如,如果您的 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. 即使您的 lambda 表达式看起来“调用”了一个方法,它也只是一个表达式,实际上不会生成对该方法的调用。
  2. 尝试以这种方式捕获方法组将很难区分同名的重载方法。

出于这个原因,我不得不想象您最好使用更传统的方法,确实涉及方法调用表达式。

【讨论】:

  • 非常有用,只要它与签名匹配,它就可以工作,唯一的问题是我必须编写 n 个方法来匹配正在使用的签名的可能性......
  • @Clint:没错。介意我问你为什么要避免方法调用语法吗?
【解决方案2】:

对于void-returning 无参数方法的情况,GetName 的签名可能如下所示:

string GetName(Expression<Func<Action>> methodExpression)

其中的Action 存在问题,要使其适用于具有其他签名的方法,您需要为其他委托类型添加大量重载。

对此的解决方案是使GetName 通用并让用户指定委托类型:

string GetName<T>(Expression<Func<T>> methodExpression)

…

GetName<Action>(() => MethodA)

这种方法的问题在于T 可以是any 类型,而不仅仅是一个委托,因此很容易错误地调用这个版本的GetName,尤其是因为GetName(() =&gt; MethodB()) 将由于类型推断,经常编译(特别是当MethodB 返回某些内容时)。

类型约束在这里对你没有帮助,你不能写where T : Delegate

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-07
    • 2017-04-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多