8
myFoo = myFoo ?? new Foo();

それ以外の

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

コードの最初の行が常に割り当てを実行すると考えるのは正しいですか?また、これはnull合体演算子の悪い使い方ですか?

4

3 に答える 3

19

生成されたコードの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はその違いさえも取り除くのに十分賢いかもしれません!

于 2009-11-24T18:29:33.557 に答える
6

これはnull合体演算子の悪い使い方ではないと思います。コードを読むとき、それは可能な限り短く簡潔であり、コードの意図は明白です。

このようにnull合体演算子を使用すると、常に割り当てが得られるのは正しいですが、私はそれについて心配する必要はありません。(そして、それが本当にパフォーマンスの問題であることが判明した場合、あなたはすでにそれを修正する方法を知っています)。

于 2009-11-24T18:08:10.027 に答える
4

あなたは、最初の行が常に割り当てを行うという点で正しいです。コードが頻繁に実行されない限り、私はそれについて心配することはありません。

于 2009-11-24T18:07:36.517 に答える