1

I have this code:

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();
    }
}

when I run it and use watch to look inside the object bound to member reference I see that MemberInfo.Name property has value <Main>b__0.

This looks weird. Why wouldn't reflection make use of whatToDo name? What if I had more that one action with the same signature inside one member function - how would I tell which one is reported?

Why is such a weird name returned by reflection?

sharptooth
  • 167,383
  • 100
  • 513
  • 979
  • 4
    It's an anonymous function, what else would you expect? This is an implementation detail, do not depend on it. – asawyer May 04 '12 at 13:59
  • http://stackoverflow.com/questions/4704910/using-methodinfo-getcurrentmethod-in-anonymous-methods – Habib May 04 '12 at 14:01
  • "Why wouldn't reflection make use of `whatToDo` name?" - with the amount of rep you've earned in [tag:c++], I *know* you know the difference between object variables and their values :) – AakashM May 04 '12 at 14:05
  • @AakashM: Sure, but there's such thing as *metadata* in .NET. Why is the name not included into metadata? – sharptooth May 04 '12 at 14:15
  • The name of what? What should it put in the metadata for this anonymous method: `a = b = c = () => { Console.WriteLine(); };` ? – AakashM May 04 '12 at 14:31
  • @AakashM: I guess any convenient solution will do. Let it be "the one closest to the `=`". Still much better than no identifier. – sharptooth May 04 '12 at 14:56

1 Answers1

9

Lambda expressions which are being converted to delegates are transformed into methods. Your code is equivalent to:

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
    }
}

... except that the compiler is smart enough to create new classes where necessary for captured variables etc. While in my transformation the extra method is called MyLambda, the C# compiler generates unspeakable names which aren't valid C# identifiers (to avoid collisions, prevent you from accessing them directly etc).

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • I seem to recall seeing an answer by you to another question directly addressing the unspeakable "weird name" that the OP refers to. – BoltClock May 04 '12 at 14:00
  • @BoltClock I know I've read answers from Eric Lippert explaining some of the details before, but I didn't favorite it regrettably. – asawyer May 04 '12 at 14:01
  • 1
    I found [this](http://stackoverflow.com/a/6402504/106224). Although that name is of an anonymous class type, it isn't all that different from anonymous delegate types... – BoltClock May 04 '12 at 14:04
  • 4
    @BoltClock That links to the post I was thinking about, awesome: http://stackoverflow.com/questions/2508828/where-to-learn-about-vs-debugger-magic-names/2509524#2509524 – asawyer May 04 '12 at 14:05