2016-03-21 3 views
0

Очевидно, что Decompiler ICSharpCode каким-то образом не декомпилирует внутренние классы, созданные компилятором C# для выражения лямбда. Рассмотрим следующий пример:Вложенные классы выражения ярлыка отсутствуют в дереве синтаксиса с помощью декомпилятора ICSharpCode

В некоторых случаях выражение lambda в C# будет скомпилировано во внутренний класс с помощью метода, содержащего тело лямбды. Например. С # код, как это:

class MyClass 
{ 
    public void MyMethod() 
    { 
     Parallel.For(0, 10, i => 
     { 
      ... = 3 * i; 
     }) 
    } 
} 

приведет к компилятором добавив внутренний класс, как показано ниже:

class MyClass 
{ 
    public void MyMethod() 
    ... 

    public class c__DisplayClass2() 
    { 
     public int i; 

     public void b__0() 
     { 
      ... = 3 * i; 
     } 
    } 
} 

(Может быть, не совсем, как это, но вы получите идею.)

сейчас проблема в том, что когда я пытаюсь построить АСТ программно из сборки MyClass с помощью ICSharpCode.Decompiler.Ast.AstBuilder, эти внутренние классы не включены в AST (все остальное в порядке). Я даже вижу эти сгенерированные классы среди аннотаций MyClass's TypeDecleration: аннотация с типом Mono.Cecil.TypeDefinition правильно перечисляет эти внутренние классы в свой NestedTypes свойство (поэтому они были правильно загружены из сборки, но не добавлены в дерево синтаксиса, а также другие , созданные вручную внутренние классы должным образом декомпилируются).

Также см этот ILSpy вопрос, который я открыл: https://github.com/icsharpcode/ILSpy/issues/686

я упускаю что-то очевидное здесь? Я также посмотрел сборку с ILSpy с помощью GUI, и там соответствующий код должным образом декомпилировался (хотя и не с внутренним классом, а с рекомбинацией лямбда).

ответ

0

У меня возникла проблема: перед работой с деревом синтаксиса нужно запустить astBuilder.RunTransformations();, что также заново создаст делегаты.

До того как я сделал это:

var assembly = AssemblyDefinition.ReadAssembly(typeof(Program).Assembly.Location); 
var decompilerContext = new DecompilerContext(assembly.MainModule); 
var astBuilder = new AstBuilder(decompilerContext); 
astBuilder.AddAssembly(assembly); 

var syntaxTree = astBuilder.SyntaxTree; 

Однако для синтаксического дерева, чтобы быть инициализирован вам это нужно:

var assembly = AssemblyDefinition.ReadAssembly(typeof(Program).Assembly.Location); 
var decompilerContext = new DecompilerContext(assembly.MainModule); 
var astBuilder = new AstBuilder(decompilerContext); 
astBuilder.AddAssembly(assembly); 
astBuilder.RunTransformations(); // This is new. 

var syntaxTree = astBuilder.SyntaxTree; 
Смежные вопросы