【问题标题】:Get the name of the first argument in an extension method?获取扩展方法中第一个参数的名称?
【发布时间】:2011-12-08 02:37:27
【问题描述】:
string thing = "etc";
thing = thing.GetName();
//now thing == "thing"

这可能吗?

public static string GetName(this object obj)
{
    return ... POOF! //should == "thing"
}

【问题讨论】:

  • 你为什么要这样做?
  • 作为一种扩展方法,我怀疑这很容易实现。另一方面,采用LambdaExpression 的方法可以做到这一点。
  • @MatthewFerreira 如果扩展方法版本不起作用,您可以告诉我如何使用 lambda 表达式来实现,我将不胜感激。但也许这应该是一个单独的问题?谢谢。
  • 据我了解,编译代码后,局部变量实际上并没有名称。编译后的代码简单引用变量1、2、3...可以通过反射获取方法参数和类成员的名称。
  • @BrokenGlass 我只是在试验。使用@Scott 的匿名类型技巧,我可以做到new {thing}.ThrowIfNull();。我猜它的性能很糟糕,但我认为我不必传入任何字符串就可以在错误消息中使用它,这很酷。

标签: c# .net reflection extension-methods stack-frame


【解决方案1】:

我同意@Reed 的回答。但是,如果你真的想实现这个功能,你可以让它工作:

string thing = "etc";
thing = new{thing}.GetName();

GetName 扩展方法将简单地使用反射从匿名对象中获取第一个属性的名称。

唯一的其他方法是使用 Lambda 表达式,但代码肯定会复杂得多。

【讨论】:

  • 这很棒。谢谢你。我还在尝试。我还在网上找到了类似的东西abdullin.com/journal/2008/12/13/…
  • @Benjamin 那篇文章正是我的想法!它甚至包括有关使用 Lambda 表达式的信息。这就像我在不知不觉中抄袭了:)
  • 遗憾的是链接已损坏,我想一直这样做以构建良好的日志记录,nameof() 解决了很多破坏行为,但我希望它是傻瓜(工程师)证明。
【解决方案2】:

没有。在您使用它时,“名称”将是“obj” - 这可以通过MethodBase.GetCurrentMethod().GetParameters()[0].Name 检索(带有调试符号)。

但是,您无法从调用方法中检索变量名称。

【讨论】:

  • 谢谢。是不是因为编译优化?
  • @Benjamin 好吧,上面的内容不适用于优化,但是没有办法通过反射来获取代码的详细信息。您可以获取方法信息和参数信息,但您需要获取传递给此方法的变量,而反射不提供该信息...
  • @Benjamin 这不是由于优化......局部变量的名称永远不会存储在编译代码中(无论有没有优化),因此它们永远不能通过反射获得。类成员的名称(属性、字段、方法和参数)存储在编译后的代码中,因此可以通过反射访问。
【解决方案3】:

如果您需要扩展方法中的原始变量名,我认为最好这样做:

thing.DoSomething(nameof(thing));

public static string DoSomething(this object obj, string name) {
    // name == "thing"
}

【讨论】:

    【解决方案4】:

    C# 6 中的新功能是nameof(),它将完全取代扩展方法。

    if (x == null) throw new ArgumentNullException(nameof(x));
    WriteLine(nameof(person.Address.ZipCode)); // prints "ZipCode”
    

    有点相关的是CallerMemberAttribute,它将获取调用函数的方法的名称。 useful comparison of the two methods,以及与 PropertyChanged 事件相关的示例,还谈到了生成的 IL 代码(TL;DR:它们是相同的)。

    【讨论】:

    • 有人愿意解释这个问题吗?随机投票没有帮助...
    • 您无法在nameof 的扩展方法中获取第一个参数的原始名称。因此,您的回答没有回答最初的问题。请再次阅读最初的问题和接受的答案。
    • @JFMG 是的,但是nameof IS OP 试图编写的扩展方法。我阅读了最初的问题并推断出他实际上在问什么,即“我如何获得变量的名称?”
    • 嗯,这是一个有趣的观点。如果您认为他实际上想编写一个扩展方法来获取变量的名称,那么您的答案是正确的。从来没想过。如果您按照他的要求看到它,那么您的答案就无关紧要了,因为使用 nameof 您无法在自己的扩展方法中获取原始调用变量名称。
    • 我不明白反对意见。 OP 想要将变量的名称作为字符串,nameof 就是这样做的。在扩展方法中获取原始名称从来都不是必需的。扩展方法只是 OP 尝试做的前者。
    猜你喜欢
    • 2016-02-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-01
    • 2011-10-09
    • 2016-10-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多