System.Reflection.Emit
現在、コード生成に関する問題に取り組んでいます。私はdefault(SomeType)
、C# で使用する場所でどの CIL を出力するかを理解しようとしています。
Visual Studio 11 Beta からいくつかの基本的な実験を実行しました。JustDecompiledefault(bool)
は、 、default(string)
、およびの次の CIL 出力を示していますdefault(int?
。
.locals init (
[0] bool V_0,
[1] string V_1,
[2] valuetype [mscorlib]System.Nullable`1<int32> V_2
)
// bool b = default(bool);
ldc.i4.0
stloc.0
// string s = default(string);
ldnull
stloc.1
// int? ni = default(int?);
ldloca.s V_2
initobj valuetype [mscorlib]System.Nullable`1<int32>
これから判断するとdefault(T)
、コンパイラによって、指定された型に最も適した CIL に解決されるようです。
次に、3 つの一般的な方法を使用して、より一般的なケースで何が起こるかを確認しました。
T CreateStructDefault<T>() where T : struct { return default(T); }
T CreateClassDefault<T>() where T : class { return default(T); }
T CreateClassNull<T>() where T : class { return null; }
3 つのメソッドはすべて同じ CIL メソッド本体を生成します。
.locals init (
[0] !!T V_0,
[1] !!T V_1
)
IL_0000: nop
IL_0001: ldloca.s V_1
IL_0003: initobj !!T
IL_0009: ldloc.1
IL_000a: stloc.0
IL_000b: br.s IL_000d
IL_000d: ldloc.0
IL_000e: ret
質問:
default(SomeType)
これらすべてから、C#は CIL に最もよく対応していると結論付けることができますか?
initobj
非プリミティブ型 (string
? を除く)ldc.iX.0
//ldnull
プリミティブ型の場合 (プラスstring
)?
そして、なぜだけではなくCreateClassNull<T>
に変換されるのでしょうか? 結局のところ、(参照型でもある)に対して発行されました。ldnull
initobj
ldnull
string