8

C#、VB、.NETを使用してアプリを作成するとします。ビルドを押すと、実際にコードがコンパイルされますか?いくつかのアセンブリでredgatesリフレクターを使い始めて、コードを逐語的に見るまで、そう思っていました。ループが展開され、さらに多くの最適化が行われることを期待していましたが、代わりに何もありませんでした。

では、コンパイルは実際にいつ行われますか?ビルドするとコードはIL(Intermediary Language)になり、実行するとCLRに読み込まれると思いますか?CLR中にのみ最適化され、ビルド時には最適化されませんか?

4

2 に答える 2

24

VSでコンパイルする場合

  1. ソースコードは、共通中間言語(CIL)またはMSIL(Microsoft中間言語)と呼ばれるバイトコードにコンパイルされます。
  2. すべてのクラスとすべてのメソッド(および他のすべてのもの:O)からのメタデータは、結果の実行可能ファイル(dllまたはexe)のPEヘッダーに含まれます。
  3. 実行可能ファイルを作成している場合、PEヘッダーには、実行可能ファイルを実行するときにCLR(共通言語ランタイム)のロードを担当する従来のブートストラッパーも含まれています。

実行する場合:

  1. ブートストラッパーはCLRを初期化し(主にmscorlibアセンブリをロードすることにより)、アセンブリを実行するように指示します。
  2. CLRはメインエントリを実行します。
  3. 現在、クラスにはメソッド関数のアドレスを保持するベクトルテーブルがあるため、MyMethodを呼び出すと、このテーブルが検索され、アドレスへの対応する呼び出しが行われます。開始時に、すべてのテーブルのすべてのエントリにJITコンパイラのアドレスがあります。
  4. そのようなメソッドの1つが呼び出されると、実際のメソッドの代わりにJITが呼び出され、制御されます。次に、JITはCILコードを適切なアーキテクチャの実際のアセンブリコードにコンパイルします。
  5. コードがコンパイルされると、JITはメソッドベクトルテーブルに入り、アドレスをコンパイルされたコードの1つに置き換えます。これにより、後続のすべての呼び出しでJITが呼び出されなくなります。
  6. 最後に、JITはコンパイルされたコードの実行を処理します。
  7. まだコンパイルされていない別のメソッドを呼び出す場合は、4に戻ります...など...

他の質問は実際にはこれについてではなかったので、私もここに答えを投稿します...

于 2009-08-05T22:56:38.740 に答える
4

コンパイル時にILにコンパイルされます。Reflectorの魔法は、ILを「理解」し、それをc#(またはVB.NETなど。Reflectorの[オプション]メニューの下を見ると、ILを含む任意の形式でアセンブリを表示できる)に変換し直すことです。

Reflectorでは、実際には元のコードが表示されていません。ILからc#への変換が表示されています。ほとんどの場合、それはあなたが書いたものと非常に似ていますが、いくつかの明白な兆候があります-たとえば、自動プロパティを実装した場所を見つけます:

string MyProperty {get;set;}

そして、それが実際に何にコンパイルされるかがわかります。これは次のようなものです。

public string MyProperty
{
    [CompilerGenerated]
    get
    {
        return this.<MyProperty>k__BackingField;
    }
    [CompilerGenerated]
    set
    {
        this.<MyProperty>k__BackingField = value;
    }
}
于 2009-08-05T22:56:03.407 に答える