Comparé el CIL del código generado (asegurándome de hacer una compilación Release - con el código de Optimize marcado en las propiedades del proyecto, que corresponde al interruptor /optimize
en csc.exe
). Esto es lo que tengo (utilizando VS 2008 - cuenta que Foo.MaybeFoo()
es un método que devuelve a veces null
, a veces un Foo
)
GetFooWithIf
:
IL_0000: call class Application3.Foo Application3.Foo::MaybeFoo()
IL_0005: stloc.0
IL_0006: ldloc.0
IL_0007: brtrue.s IL_000f
IL_0009: newobj instance void Application3.Foo::.ctor()
IL_000e: stloc.0
IL_000f: ldloc.0
IL_0010: ret
GetFooWithCoalescingOperator
:
IL_0000: call class Application3.Foo Application3.Foo::MaybeFoo()
IL_0005: stloc.0
IL_0006: ldloc.0
IL_0007: dup
IL_0008: brtrue.s IL_0010
IL_000a: pop
IL_000b: newobj instance void Application3.Foo::.ctor()
IL_0010: stloc.0
IL_0011: ldloc.0
IL_0012: ret
Por lo tanto, la mismo, excepto por una duplicación de la parte superior superior de la pila y pop. Si esto se puede hacer para hacer una diferencia de rendimiento mensurable, compraré un sombrero específicamente para el propósito de comerlo; por lo tanto, vaya con el que sienta que ofrece una mejor legibilidad.
(corregir) ¡oh, y JITter puede ser lo suficientemente inteligente como para deshacerse de esa diferencia!
Hace un argumento convincente para el operador '?? =' :) –
@PavelMinaev en este caso, ¿no es idéntico al operador '|| ='? Tendría que reemplazar una llamada 'if (! Isset (myFoo)) myFoo = new Foo();' para garantizar su propio operador –
No es idéntico, ya que '||' requiere un valor booleano. –