0

どうやら ICSharpCode Decompiler は、ラムダ式の C# コンパイラによって作成された内部クラスをどうにかして逆コンパイルしません。次の例を検討してください。

場合によっては、C# のラムダ式は、ラムダの本体を含むメソッドを使用して内部クラスにコンパイルされます。たとえば、次のような 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を使用してアセンブリからプログラムで AST を構築しようとすると、ASTICSharpCode.Decompiler.Ast.AstBuilderに含まれないことです (他のすべては問題ありません)。MyClassの注釈の中にこれらの生成されたクラスを見ることさえできますTypeDecleration:型の注釈は、Mono.Cecil.TypeDefinitionこれらの内部クラスをそのNestedTypesプロパティに正しくリストします(したがって、それらはアセンブリから適切にロードされましたが、構文ツリーには追加されませんでした;他の、手動で作成された内部クラスは適切に逆コンパイルされます)。

私が開いたこの ILSpy の問題も参照してください: https://github.com/icsharpcode/ILSpy/issues/686

ここで明らかな何かが欠けていますか?また、GUI を使用して ILSpy からのアセンブリを調べたところ、問題のコードは適切に逆コンパイルされています (内部クラスではなく、ラムダが再構築されています)。

4

1 に答える 1

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;
于 2016-03-22T14:18:22.813 に答える