Подтвердить что ты не робот

Что означает имя DisplayClass при вызове лямбда?

В соответствии с этим ответом, когда код использует локальные переменные из внутренних лямбда-методов, компилятор будет генерировать дополнительные классы, которые могут иметь имя, например c__DisplayClass1. Например, следующий (совершенно бесполезный) код:

class Program
{
    static void Main()
    {
        try {
            implMain();
        } catch (Exception e) {
            Console.WriteLine(e.ToString());
        }
    }

    static void implMain()
    {
        for (int i = 0; i < 10; i++) {
            invoke(() => {
                Console.WriteLine(i);
                throw new InvalidOperationException();
            });
        }
    }
    static void invoke(Action what)
    {
        what();
    }
}

выводит следующий стек вызовов:

System.InvalidOperationException
at ConsoleApplication1.Program.<>c__DisplayClass2.<implMain>b__0()
at ConsoleApplication1.Program.invoke(Action what)
at ConsoleApplication1.Program.implMain()
at ConsoleApplication1.Program.Main()

Обратите внимание, что там есть c__DisplayClass2, который является именем класса, сгенерированного компилятором, для хранения переменной цикла.

Согласно этот ответ c__DisplayClass "означает"

c → класс закрытия анонимного метода ( "DisplayClass" )

Хорошо, но что здесь означает "DisplayClass"?

Что делает этот сгенерированный класс "отображением"? Другими словами, почему это не "MagicClass" или "GeneratedClass" или любое другое имя?

4b9b3361

Ответ 1

Из ответ на соответствующий вопрос Эрика Липперта:

Причина, по которой класс закрытия называется "DisplayClass", немного неудачна: это жаргон, используемый командой отладчика для описания класса, который имеет особое поведение при отображении в отладчике. Очевидно, что мы не хотим отображать "x" в качестве поля класса с невозможным именем при отладке вашего кода; скорее, вы хотите, чтобы он выглядел как любая другая локальная переменная. В отладчике есть специальная передача для обработки этого класса отображения. Вероятно, его, скорее всего, назовем "ClosureClass", чтобы было проще читать разборку.

Ответ 2

Вы можете получить некоторое представление от источника компилятора С#, доступного из подкаталога SSCLI20, csharp/sccomp. Поиск кода для "отображения" дает большинство обращений в файле исходного кода fncbind.cpp. Вы увидите, что он используется в кодовых символах, а также в комментариях.

В комментариях настоятельно предлагается, чтобы это был термин, используемый внутри команды командой, возможно, еще в рамках проектных совещаний. Это старинный код .NET 2.0, еще не было перезаписи кода. Просто итераторы и анонимные методы, реализованные аналогичным образом. Термин "класс отображения" смещается от "пользовательского класса" в комментариях, что ясно указывает на то, что они использовали термин для обозначения автоматически сгенерированных классов. Нет сильного намека на то, почему "дисплей" был одобрен, я подозреваю, что он может иметь какое-то отношение к этим классам, видимым в метаданных сборки.

Ответ 3

На основе Reflector DisplayClass можно перевести как CompilerGeneratedClass

[CompilerGenerated]
private sealed class <>c__DisplayClass16b
{
// Fields
public MainForm <>4__this;
public object sender;

// Methods
public void <cmdADSInit_Click>b__16a()
  {
    ADS.Initialize();
    this.<>4__this._Sender = this.sender;
    this.<>4__this.SelectedObject = ADS.Instance;
  }
}