2012-05-04 2 views
1

У меня есть этот код:Почему отражение возвращает такое странное имя для лямбды?

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

, когда я запускаю его и использовать часы, чтобы заглянуть внутрь объекта, связанного с member ссылкой я вижу, что MemberInfo.Name свойство имеет значение <Main>b__0.

Это выглядит странно. Почему бы не использовать отражение whatToDo? Что, если бы у меня было больше одного действия с одной и той же сигнатурой внутри одной функции-члена - как бы я сказал, какой из них сообщается?

Почему такое странное имя возвращается отражением?

+4

Это анонимная функция, что еще вы ожидаете? Это деталь реализации, не зависит от нее. – asawyer

+0

http://stackoverflow.com/questions/4704910/using-methodinfo-getcurrentmethod-in-anonymous-methods – Habib

+0

«Почему бы не использовать отражение имени' whatToDo'? - с суммой репутации, которую вы заработали в [tag: C++], я * знаю * вы знаете разницу между объектными переменными и их значениями :) – AakashM

ответ

9

Лямбда-выражения, которые преобразуются в делегаты, преобразуются в методы. Ваш код эквивалентен:

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# (чтобы избежать коллизий, препятствовать доступу к ним напрямую и т. д.).

+0

Кажется, я вспомнил, что увидел ответ на другой вопрос, непосредственно обращаясь к невыразимому «странному имени», к которому относится OP. – BoltClock

+0

@BoltClock Я знаю, что читал ответы от Эрика Липперта, объясняющие некоторые подробности, но я не любил его, к сожалению. – asawyer

+1

Я нашел [это] (http://stackoverflow.com/a/6402504/106224). Хотя это имя имеет тип анонимного класса, это не все, что отличается от анонимных типов делегатов ... – BoltClock