myFoo = myFoo ?? new Foo();
而不是
if (myFoo == null) myFoo = new Foo();
我认为第一行代码总是会执行作业吗?另外,这是否使用空合并运算符?
答案 0 :(得分:19)
我比较了生成代码的CIL(确保执行发布版本 - 在项目属性中选中了Optimize Code,这与/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可能足够聪明,甚至可以摆脱这种差异!
答案 1 :(得分:6)
我认为这不是使用null-coalescing运算符。在阅读代码时,它尽可能简洁明了,代码的意图也很明显。
使用像这样的null-coalescing运算符是正确的,你总是得到一个赋值,但我不担心。 (如果它真的结果是性能问题,那么你已经知道如何修复它了。)
答案 2 :(得分:4)
你是对的,因为第一行总是会进行作业。除非代码经常执行,否则我不担心。