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可能足够聪明,甚至可以消除这种差异!

10-08 15:12