空合并运算符使用不当?

发布于 2024-08-12 10:41:47 字数 178 浏览 3 评论 0原文

myFoo = myFoo ?? new Foo();

而不是

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

我认为第一行代码将始终执行分配的想法是否正确?另外,这是空合并运算符的错误使用吗?

myFoo = myFoo ?? new Foo();

instead of

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

Am I correct in thinking that the first line of code will always perform an assignment? Also, is this a bad use of the null-coalescing operator?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

北城挽邺 2024-08-19 10:41:47

我比较了生成代码的 CIL(确保进行发布构建 - 在项目属性中选中优化代码,这对应于 csc.exe 上的 /optimize 开关>)。这就是我得到的(使用 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 可能足够聪明,甚至可以消除这种差异!

I compared the CIL of the generated code (making sure to do a Release build - with Optimize Code checked in the Project Properties, which corresponds to the /optimize switch on csc.exe). This is what I got (using VS 2008 - note that Foo.MaybeFoo() is a method that sometimes returns null, sometimes a 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

Thus, the same except for an extra top-of-stack-duplication and pop. If this can be made to make a measurable performance difference, I will purchase a hat specifically for the purpose of eating it; therefore, go with the one that you feel offers better readability.

(edit) oh, and the JITter might be clever enough to get rid of even that difference!

老旧海报 2024-08-19 10:41:47

我不认为这是对空合并运算符的错误使用。阅读代码时,尽量简短、简洁,代码的意图很明显。

使用这样的空合并运算符是正确的,您总是会得到一个赋值,但我不会担心这一点。 (如果事实证明它确实是性能问题,那么您已经知道如何解决它)。

I don't think this a bad use of the null-coalescing operator. When reading the code, it is as short and concise as possible, and the intent of the code is obvious.

It is correct that using the null-coalescing operator like this, you will always get an assignment, but I would not worry about that. (And if it really turns out to be a performance issue, you already know how to fix it).

心碎的声音 2024-08-19 10:41:47

你是正确的,第一行总是会进行分配。除非代码经常执行,否则我不会担心这一点。

You are correct in that the first line will always make an assignment. I would not worry about that unless the code is executed very often.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文