Null Coalescing Operator的使用不当?

时间:2009-11-24 18:02:54

标签: c# null-coalescing-operator

myFoo = myFoo ?? new Foo();

而不是

if (myFoo == null) myFoo = new Foo();

我认为第一行代码总是会执行作业吗?另外,这是否使用空合并运算符?

3 个答案:

答案 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)

你是对的,因为第一行总是会进行作业。除非代码经常执行,否则我不担心。