В настоящее время я работаю над проблемой, связанной с генерированием кода System.Reflection.Emit
. Я пытаюсь понять, что CIL испускает в местах, где я бы использовал default(SomeType)
в С#.
Я провел несколько базовых экспериментов из бета-версии Visual Studio 11. JustDecompile показывает мне следующий вывод CIL для default(bool)
, default(string)
и 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 для данных типов.
Я продолжал видеть, что произойдет в более общем случае, используя три общих метода:
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; }
Все три метода производят одно и то же тело метода 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)
наиболее близко соответствует CIL's & hellip;
-
initobj
для не-примитивных типов (кромеstring
?) -
ldc.iX.0
/ldnull
/и т.д. для примитивных типов (плюсstring
)?
И почему CreateClassNull<T>
не просто переводит на ldnull
, а на initobj
вместо этого? В конце концов, ldnull
испущен для string
(который также является ссылочным типом).