【问题标题】:Why does reflection return such a weird name for a lambda?为什么反射会为 lambda 返回如此奇怪的名称?
【发布时间】:2012-05-04 13:57:21
【问题描述】:

我有这个代码:

class Program
{
    static void Main(string[] args)
    {
        Action whatToDo = () => {
            var member = (MemberInfo)(MethodBase.GetCurrentMethod());
            Thread.Sleep(0); //whatever, need something to put a breakpoint on
        };
        whatToDo();
    }
}

当我运行它并使用 watch 查看绑定到 member 引用的对象内部时,我看到 MemberInfo.Name 属性的值 <Main>b__0

这看起来很奇怪。为什么反射不使用whatToDo 名称?如果我在一个成员函数中有多个具有相同签名的操作怎么办 - 我如何判断报告了哪一个?

为什么反射会返回这么奇怪的名字?

【问题讨论】:

  • 这是一个匿名函数,你还能期待什么?这是一个实现细节,不要依赖它。
  • "反射为什么不使用whatToDo名字?" - 以你在c++ 中获得的代表数量,我知道你知道对象变量和它们的值之间的区别:)
  • @AakashM:当然可以,但是在 .NET 中有像 metadata 这样的东西。为什么名称不包含在元数据中?
  • 什么名字?它应该在这个匿名方法的元数据中添加什么:a = b = c = () => { Console.WriteLine(); };

标签: c# .net reflection lambda


【解决方案1】:

被转换为委托的 Lambda 表达式被转换为方法。您的代码相当于:

class Program
{
    static void Main(string[] args)
    {
        Action whatToDo = MyLambda; // Method group conversion
        whatToDo();
    }

    static void MyLambda()
    {
        var member = (MemberInfo)(MethodBase.GetCurrentMethod());
        Thread.Sleep(0); //whatever, need something to put a breakpoint on
    }
}

...除了编译器足够聪明,可以在必要时为捕获的变量等创建新类。虽然在我的转换中,额外的方法称为 MyLambda,但 C# 编译器会生成 难以描述的名称这不是有效的 C# 标识符(为了避免冲突,防止您直接访问它们等)。

【讨论】:

  • 我似乎记得看到你对另一个问题的回答直接解决了 OP 所指的难以形容的“奇怪的名字”。
  • @BoltClock 我知道我之前读过 Eric Lippert 的回答,解释了一些细节,但遗憾的是我没有喜欢它。
  • 我找到了this。尽管该名称属于匿名类类型,但它与匿名委托类型并没有什么不同...
  • @BoltClock 链接到我正在考虑的帖子,太棒了:stackoverflow.com/questions/2508828/…
猜你喜欢
  • 1970-01-01
  • 2020-02-28
  • 2019-01-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-01
  • 1970-01-01
相关资源
最近更新 更多