現在、私はSystem.Reflection.Emit
コードの生成に関する問題に取り組んでいます。私はC#でdefault(SomeType)
を使用する場所でCILがどのように放射するかを調べようとしています。"default(SomeType)"をC#からCILに変換するにはどうすればいいですか?
私はVisual Studio 11 Betaから基本的な実験をいくつか実行しました。 JustDecompileは私にdefault(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に、コンパイラによって解決を取得するようです。
.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
:
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のメソッド本体を生成:は、私は3つの汎用メソッドを使用して、より一般的な場合に何が起こるか見に行きました
質問:
C#のdefault(SomeType)
がCILの&hellipに最も近いと結論づけることはできますか? (string
除く?)非プリミティブ型の
initobj
ldc.iX.0
/ldnull
/などのプリミティブ型(プラスstring
)のために?
そして、なぜCreateClassNull<T>
はちょうどldnull
に変換されませんが、その代わりinitobj
か?結局のところldnull
は、(これも参照型です)に対して発行されました。
「プリミティブ」タイプはどういう意味ですか?値型と参照型があります。 \ – sehe
"プリミティブ型"では、CTS(?)でサポートされているものを指しています - 'bool'、' byte'、 'char'、' int '、' float'、 'double'などです。ユーザー定義の値や参照型と異なり、より基本的な型に分解することはできません。 – stakx
私は、コンパイラが次の命令への分岐を削除しなかったので、最適化されていないデバッグを見なければならないことに注意してください。 –