0

.net デコンパイラーでは、コンストラクターのコードが表示されません。多くの .net 逆コンパイラでテストしましたが、コンストラクタ コードを表示するものはありません。そのコードを示すデコンパイラはありますか。

前もって感謝します ここに画像の説明を入力

4

2 に答える 2

4

C# で定義されたすべての .NET 型 (VB.NET や他の言語でこれがどのように行われるかはわかりません。同じように行う場合とそうでない場合があります) には、コンストラクターがあります。

コンストラクターを明示的に追加しない場合は、コンパイラーによって提供されます。

私は (以前に) Telerik デコンパイラ、Reflector、および JetBrains による dotPeek をテストしました。表示するコードがある場合、それらはすべてコンストラクタ コードを表示します。

のコンストラクターを示す dotPeek 1.1 は次のTuple<T1, T2>とおりです。

dotPeek 1.1 によって逆コンパイルされた Tuple<T1, T2> コンストラクター

ただし、逆コンパイラは、元のソース コードを認識できないため、コンストラクタを削除することを選択する場合があります。代わりに、指定した IL を生成するコードの種類を推測しようとします。したがって、コードが空のコンストラクターを明示的に書き出す場合でも、それがなくてもコンパイラーが提供するものと 100% 同一にコンパイルされ、逆コンパイラーは空のコンストラクターを書き出さなかったと想定する可能性があります。

TL;DR : MultipleLookupField コンストラクターのドキュメントから判断すると、パラメーターはありません。したがって、その唯一の目的は基本コンストラクターを呼び出すことだけであり、他には何もない可能性があります。そのため、ソースコードにも書き出されていない可能性が高いため、逆コンパイルする必要はまったくないかもしれません。

ただし、すべてのクラスにコンストラクターがあることを示すために、いくつかの例を見てみましょう。

次の例は、コードを実行し、結果の上にある [IL] ボタンをクリックして逆コンパイルされた IL を表示することにより、 LINQPadでテストできます。LINQPad の逆コンパイラ (mono.cecil だと思います) は、この種の推論を同じレベルで行わないため、コンストラクタが表示されます。

例 1: コンストラクターまたはコンストラクターに配置されるコードがない

void Main()
{
    var t = new Test();
    t.Execute();
}

public class Test
{
    public void Execute()
    {
        Debug.WriteLine("Execute");
    }
}

生成された IL:

IL_0000:  newobj      UserQuery+Test..ctor
IL_0005:  stloc.0     // t
IL_0006:  ldloc.0     // t
IL_0007:  callvirt    UserQuery+Test.Execute

Test.Execute:
IL_0000:  ldstr       "Execute"
IL_0005:  call        System.Diagnostics.Debug.WriteLine
IL_000A:  ret         

Test..ctor:
IL_0000:  ldarg.0     
IL_0001:  call        System.Object..ctor
IL_0006:  ret     

ご覧のとおり、そこにはコンストラクターがありますが、それが行うのは から基本コンストラクターを呼び出すことだけSystem.Objectです。

例 2: デフォルト値を持つ文字列フィールドを追加する

このフィールドをクラスに追加します。

public class Test
{
    private string _Value = string.Empty;

    public void Execute()
    {
        Debug.WriteLine("Execute");
    }
}

再実行すると、生成された IL が次のようになります。

IL_0000:  newobj      UserQuery+Test..ctor
IL_0005:  stloc.0     // t
IL_0006:  ldloc.0     // t
IL_0007:  callvirt    UserQuery+Test.Execute

Test.Execute:
IL_0000:  ldstr       "Execute"
IL_0005:  call        System.Diagnostics.Debug.WriteLine
IL_000A:  ret         

Test..ctor:
IL_0000:  ldarg.0     
IL_0001:  ldsfld      System.String.Empty
IL_0006:  stfld       UserQuery+Test._Value
IL_000B:  ldarg.0     
IL_000C:  call        System.Object..ctor
IL_0011:  ret 

ご覧のとおり、初期化コードはコンストラクターに「リフト」されたため、コンストラクターはフィールドを初期化します。

例 3: 初期化をコンストラクターに移動する

クラスを次のように変更しましょう。

public class Test
{
    private string _Value;

    public Test()
    {
        _Value = string.Empty;
    }

    public void Execute()
    {
        Debug.WriteLine("Execute");
    }
}

コンストラクターの IL は次のとおりです。

Test..ctor:
IL_0000:  ldarg.0     
IL_0001:  call        System.Object..ctor
IL_0006:  ldarg.0     
IL_0007:  ldsfld      System.String.Empty
IL_000C:  stfld       UserQuery+Test._Value
IL_0011:  ret 

ここでの違いは、コンストラクター内のコードの順序です。フィールドは、基本コンストラクターが呼び出されたに初期化されますが、前の例では以前に初期化されていました。

結論

これらの型にはコンストラクターがないか、それらの逆コンパイラーが、宣言とコンストラクターでのフィールドの初期化の違いを認識していない可能性があります。ただし、後者はありそうもないので、クラスにはコンストラクターがないと仮定します。

于 2013-10-09T11:35:50.870 に答える
1

Telerik JustDecompileは、コンストラクター コードを示しています。

于 2013-10-09T11:30:12.400 に答える