Почему не декомпелируется этот код ?
От: Аноним  
Дата: 30.08.07 08:27
Оценка:
Читаю эту
Автор(ы): Patrick Smacchia
Дата: 30.07.2006
Статья представляет новое свойство языка C# версии 2.0, называемое анонимными методами.
статью.
Попытался в Reflector декомпелировать этот код как там написано:
using System.Threading;

class Program 
{
  static void Main() 
  {
    for (int i = 0; i < 5; i++)
    {
      int j = i;
      ThreadPool.QueueUserWorkItem(
        delegate { System.Console.WriteLine(j); }, null);
    }
  }
}

Однако вместо вот такого кода:
private static void Main()
{
  Program.<>c__DisplayClass1 class1;
  bool flag1;
  int num1 = 0;
  goto Label_0029;
Label_0004:
  class1 = new Program.<>c__DisplayClass1();
  class1.j = num1;
  ThreadPool.QueueUserWorkItem(new WaitCallback(class1.<Main>b__0), null);
  num1++;
Label_0029:
  flag1 = num1 < 5;
  if (flag1) 
  {
    goto Label_0004;
  }
}

Получаю такой:
private static void Main()
{
    for (int i = 0; i < 5; i++)
    {
        int j = i;
        ThreadPool.QueueUserWorkItem(delegate {
            Console.WriteLine(j);
        }, null);
    }
}

Почему? Как получить "правильный код"? В нескольких аналогичных случаях результат такой-же!
Использую: Reflector ver.5.0.32.0 !
Рушится самообразование помогите
Re: Почему не декомпелируется этот код ?
От: nikov США http://www.linkedin.com/in/nikov
Дата: 30.08.07 08:36
Оценка:
Здравствуйте, Аноним, Вы писали:

А> Однако вместо вот такого кода:

А> Получаю такой:

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

Я замечал, что последние версии Reflector'а во многих случаях неплохо справляются с восстановлением читабельного кода, но возможно, это не всегда получается.
Re: Почему не декомпелируется этот код ?
От: _FRED_ Черногория
Дата: 30.08.07 08:52
Оценка: +1
Здравствуйте, Аноним, Вы писали:

А> Почему? Как получить "правильный код"? В нескольких аналогичных случаях результат такой-же!

А> Использую: Reflector ver.5.0.32.0 !
А> Рушится самообразование помогите

Иди в меню рефлектора: view\Options… -> Disassembler -> Optimization и выставляй None
Help will always be given at Hogwarts to those who ask for it.
Re[2]: Почему не декомпелируется этот код ?
От: Аноним  
Дата: 30.08.07 09:06
Оценка:
Здравствуйте, nikov, Вы писали:

N>По-моему Вы случайно перепутали местами "плохой" и "хороший" код.


Нет не перепутал. В моем случае стоит задача понять, что компилятор делает с анонимными методами. Взять это пример:
class Program 
{
  delegate int DelegateTypeCounter();

  static DelegateTypeCounter MakeCounter()
  {
    int counter = 0;
    DelegateTypeCounter delegateInstanceCounter = 
      delegate { return ++counter; };
    return delegateInstanceCounter;
  }

  static void Main() 
  {
    DelegateTypeCounter counter1 = MakeCounter();
    DelegateTypeCounter counter2 = MakeCounter();
    System.Console.WriteLine(counter1());
    System.Console.WriteLine(counter1());
    System.Console.WriteLine(counter2());
    System.Console.WriteLine(counter2());
  }
}

Компилятор создаёт класс с именем <>c__DisplayClass1:
[CompilerGenerated]
private sealed class <>c__DisplayClass1
{
    public int counter;

    public int <MakeCounter>b__0()
    {
        return ++this.counter;
    }
}

А для метода MakeCounter() автор статьи приводит следующий листинг:
private static Program.DelegateTypeCounter MakeCounter()
{
   Program.<>c__DisplayClass1 <>8__locals2 = new Program.<>c__DisplayClass1();
   <>8__locals2.counter = 0;
   return new Program.DelegateTypeCounter(<>8__locals2.<MakeCounter>b__0);
}

Из этих двух листингов понятно, что компилятор делает с анонимными метода. Вот только у себя я ни чего подобного получить не могу. Это меня сильно расстраивает поскольку хотелось-бы посмотреть, что делает компилятор и в других случаях !
Причем автор это делает в Reflectore. Но когда я пытаюсь де компилировать код он показывает нечто совсем другое:
  static DelegateTypeCounter MakeCounter()
  {
    int counter = 0;
    return delegate { return ++counter; };
  }

Что делать
Re[3]: Почему не декомпелируется этот код ?
От: nikov США http://www.linkedin.com/in/nikov
Дата: 30.08.07 09:13
Оценка:
Здравствуйте, Аноним, Вы писали:

N>>По-моему Вы случайно перепутали местами "плохой" и "хороший" код.


А> Нет не перепутал. В моем случае стоит задача понять, что компилятор делает с анонимными методами. Взять это пример:


А, ну тогда понизить уровень оптимизации до None или .NET 1.0, либо смотреть прямо IL.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.