myFoo = myFoo ?? new Foo();
代替
if (myFoo == null) myFoo = new Foo();
我认为代码的第一行将始终执行分配是正确的吗?另外,这是否对null-coalescing运算符不好用?
最佳答案
我比较了生成代码的CIL(确保执行发布版本-在项目属性中选中了优化代码,这与/optimize
上的csc.exe
开关相对应)。这就是我得到的(使用VS 2008-请注意Foo.MaybeFoo()
是有时返回null
,有时返回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
因此,除了额外的栈顶复制和弹出之外,其他都是相同的。如果可以通过这种方式来显着改善性能,我将专门购买帽子以供食用。因此,请选择您认为具有更好可读性的代码。
(编辑)哦,JITter可能足够聪明,甚至可以消除这种差异!