2016-03-21 2 views
0

Offenbar dekompiliert ICSharpCode Decompiler irgendwie innere Klassen nicht, die vom C# -Compiler für einen Lambda-Ausdruck erstellt wurden. Betrachten Sie das folgende Beispiel:Verschachtelte Klassen des Lambda-Ausdrucks fehlen im Syntaxbaum mit ICSharpCode Decompiler

In bestimmten Fällen wird ein Lambda-Ausdruck in C# in eine innere Klasse mit einer Methode kompiliert, die den Lambda-Körper enthält. Z.B. ein C# -Code wie folgt aus:

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

im Compiler führt wie unten eine innere Klasse hinzufügen:

class MyClass 
{ 
    public void MyMethod() 
    ... 

    public class c__DisplayClass2() 
    { 
     public int i; 

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

(Vielleicht nicht genau wie dieses, aber Sie bekommen die Idee.)

Jetzt Das Problem ist, dass, wenn ich versuche, eine AST programmatisch aus der Assembly von MyClass mit ICSharpCode.Decompiler.Ast.AstBuilder zu erstellen, diese inneren Klassen sind nicht in der AST enthalten (alles andere ist in Ordnung). Ich kann sogar diese generierten Klassen unter den Annotationen MyClass 's TypeDecleration sehen: die Annotation mit dem Typ Mono.Cecil.TypeDefinition listet diese inneren Klassen korrekt in ihrer NestedTypes Eigenschaft auf (also wurden sie richtig aus der Assembly geladen, aber nicht zum Syntaxbaum hinzugefügt; manuell erstellte innere Klassen werden ordnungsgemäß dekompiliert).

Siehe auch diese ILSpy Frage, die ich geöffnet: https://github.com/icsharpcode/ILSpy/issues/686

Bin ich etwas offensichtlich hier fehlt? Ich habe auch die Assembly von ILSpy über die GUI angeschaut und dort wird der betreffende Code richtig dekompiliert (allerdings nicht mit einer inneren Klasse, sondern das Lambda wird rekonstruiert).

Antwort

0

Ich habe das Problem herausgefunden: Sie müssen astBuilder.RunTransformations(); ausführen, bevor Sie mit dem Syntaxbaum arbeiten, der auch Delegaten neu erstellt.

Bevor ich tat dies:

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; 

jedoch für den Syntaxbaum richtig initialisiert werden Sie müssen dies:

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;