Null Coalescing Operator的使用不当?

Chr*_*yer 8 c# null-coalescing-operator

myFoo = myFoo ?? new Foo();
Run Code Online (Sandbox Code Playgroud)

代替

if (myFoo == null) myFoo = new Foo();
Run Code Online (Sandbox Code Playgroud)

我是否认为第一行代码将始终执行赋值?此外,这是否使用空合并运算符?

Aak*_*shM 19

我比较了生成的代码的CIL(确保执行Release版本 - 在Project Properties中选中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
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

因此,除了额外的堆栈复制和弹出之外,相同.如果可以做出可衡量的性能差异,我会专门为了吃它而购买一顶帽子; 因此,请选择您认为具有更好可读性的产品.

(编辑)哦,JITter可能足够聪明,甚至可以摆脱这种差异!


dri*_*iis 6

我不认为这是null-coalescing运算符的错误用法.在阅读代码时,它尽可能简洁明了,代码的意图是显而易见的.

使用像这样的null-coalescing运算符是正确的,你总是得到一个赋值,但我不担心.(如果它确实是一个性能问题,你已经知道如何解决它).