Dati i due metodi:anziché callvirt in caso di nuova C# 6 "?" nullo controllare
static void M1(Person p)
{
if (p != null)
{
var p1 = p.Name;
}
}
static void M2(Person p)
{
var p1 = p?.Name;
}
Perché l'uso M1 IL codice callvirt
:
IL_0007: brfalse.s IL_0012
IL_0009: nop
IL_000a: ldarg.0
IL_000b: callvirt instance string ConsoleApplication4.Person::get_Name()
e M2 IL utilizzano call
:
brtrue.s IL_0007
IL_0004: ldnull
IL_0005: br.s IL_000d
IL_0007: ldarg.0
IL_0008: call instance string ConsoleApplication4.Person::get_Name()
posso solo immaginare che perché in M2 sappiamo che p
non è nullo e corrisponde a
new MyClass().MyMethod();
È vero?
Se lo è, cosa succede se p
sarà null in altro thread?
Sarebbe bello mostrare come viene chiamato un membro virtuale effettivo quando sottoposto a override. Specificamente in presenza di '? .'. Qual è il comportamento quando un membro sottoposto a override viene 'sealed' e invocato in modo specifico? Se è ancora 'callvirt', potrebbe essere un'opportunità di ottimizzazione in Roslyn :) – leppie
@leppie C# genera' callvirt' per questo. Ma non so cosa succederà al runtime. –