Attualmente sto lavorando su un problema che riguarda la generazione del codice System.Reflection.Emit
. Sto cercando di capire cosa CIL emettere in posti dove vorrei usare default(SomeType)
in C#.Come tradurre "default (SomeType)" da C# a CIL?
Ho eseguito alcuni esperimenti di base da Visual Studio 11 Beta. JustDecompile mi mostra il seguente output CIL per default(bool)
, default(string)
, e 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>
A giudicare da questo, default(T)
sembra avere risolto dal compilatore per il CIL più appropriato per i tipi dati.
Sono andato a vedere cosa sarebbe successo nel caso più generale, utilizzando tre metodi generici:
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; }
Tutti e tre i metodi producono lo stesso metodo del corpo 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
Domanda:
Posso concludere da tutto ciò che C# 's default(SomeType)
corrisponde più strettamente a CIL's & hellip;
initobj
per i tipi non primitivi (ad eccezionestring
?)ldc.iX.0
/ldnull
/ecc per i tipi primitivi (piùstring
)?
E perché fa CreateClassNull<T>
non solo si traducono in ldnull
, ma per initobj
invece? Dopo tutto, è stato emesso ldnull
per string
(che è anche un tipo di riferimento).
cosa intendi con tipi "primitivi"? Esistono tipi di valore e tipi di riferimento. Mi aspetterei ldnull con i tipi di riferimento (inclusa la stringa). \ – sehe
Con "tipi primitivi", mi riferisco a quelli supportati nativamente dal CTS (?) - 'bool',' byte', 'char',' int ',' float', 'double', ecc. Quelli che, a differenza del valore definito dall'utente o dei tipi di riferimento, non sono compositi e non possono essere scomposti in altri tipi di base. – stakx
Osservo che si deve guardare il debug, codegen non ottimizzato, dato che il compilatore non ha rimosso un ramo per l'istruzione successiva. –