滅入るんるん

何か書きます

【C#】ReSharperを使ってCILを見る

こないだセールで買ったReSharperですが、さっそくReSharperの機能をことごとくオフにしていってしましました。
(決してReSharperが重いということはない(建前)けど、VisualStudio標準のサジェストとかが優秀になってきたからそのあたりはわざわざReSharperじゃなくていいやということです)

その中で、唯一ReSharperの強みがあってIL Viewerです。

表示の仕方は簡単で、ツールバーのRESHARPERからTools => IL Codeと押すだけです。
最新のCILを反映させるにはビルドする必要があります。

最初のコード

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SampleProject1
{
    class CilTest
    {
        private readonly string text = "";

        public void Main()
        {
            Console.WriteLine("Hello CIL!");
        }

        public string Text => string.Empty;
    }
}

無駄にusingしてたりしますが、このコードのCILを眺めましょう

.class private auto ansi beforefieldinit 
  SampleProject1.CilTest
    extends [mscorlib]System.Object
{

  .field private initonly string text

  .method public hidebysig instance void 
    Main() cil managed 
  {
    .maxstack 8

    // [15 13 - 15 45]
    IL_0000: ldstr        "Hello CIL!"
    IL_0005: call         void [mscorlib]System.Console::WriteLine(string)

    // [16 9 - 16 10]
    IL_000a: ret          

  } // end of method CilTest::Main

  .method public hidebysig specialname instance string 
    get_Text() cil managed 
  {
    .maxstack 8

    // [18 31 - 18 43]
    IL_0000: ldsfld       string [mscorlib]System.String::Empty
    IL_0005: ret          

  } // end of method CilTest::get_Text

  .method public hidebysig specialname rtspecialname instance void 
    .ctor() cil managed 
  {
    .maxstack 8

    // [11 9 - 11 43]
    IL_0000: ldarg.0      // this
    IL_0001: ldstr        ""
    IL_0006: stfld        string SampleProject1.CilTest::text
    IL_000b: ldarg.0      // this
    IL_000c: call         instance void [mscorlib]System.Object::.ctor()
    IL_0011: ret          

  } // end of method CilTest::.ctor

  .property instance string Text() 
  {
    .get instance string SampleProject1.CilTest::get_Text() 
  } // end of property CilTest::Text
} // end of class SampleProject1.CilTest

現状わかるものから考察していきましょう

  • System.Objectを継承している
    • コード上では省略していいけど実際には継承しているというのはCIL的にわかるようですね
  • .field => フィールド
  • initonly => readonly
  • .method => メソッド
    • instance => インスタンスメソッド
  • ldstrで文字列をスタックに格納
  • callでメソッド呼び出し
    • CILについていろいろと調べると仮想メソッドは別の呼び出し方法があるみたいですね
  • ret => return
  • getter only propertyはget_{PropertyName}というメソッドが生える
  • ldsfld => static fieldをスタックに格納?
  • コンストラクターは.ctorメソッドになる
  • stfld => フィールドに値をセット?
  • .property => プロパティ

CILについて全く知識がないので正確ではないことを言ってるかもしれないですがC#側からこれらのことを推測しました。

CILについては冬に時間と金(書籍購入)をかけてやっていきたかったのですが、Fodyで使いそうなので急ぎの調査という感じです。


ついでに購入予定の書籍紹介(他にいいのあれば教えて)(というか1つ目以外買っちゃった)