myFoo = myFoo ?? new Foo();
代替
if (myFoo == null) myFoo = new Foo();
我认为第一行代码将始终执行分配是否正确?此外,这是对 null-coalescing 运算符的错误使用吗?
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 可能足够聪明,甚至可以消除这种差异!
我不认为这是对空合并运算符的不好使用。阅读代码时,尽量简短简洁,代码意图明显。
使用像这样的空合并运算符是正确的,你总是会得到一个赋值,但我不会担心这一点。(如果它真的是一个性能问题,你已经知道如何解决它)。
您是正确的,第一行将始终进行分配。除非代码经常执行,否则我不会担心这一点。