myFoo = myFoo ?? new Foo();
それ以外の
if (myFoo == null) myFoo = new Foo();
コードの最初の行が常に割り当てを実行すると考えるのは正しいですか?また、これはnull合体演算子の悪い使い方ですか?
myFoo = myFoo ?? new Foo();
それ以外の
if (myFoo == null) myFoo = new Foo();
コードの最初の行が常に割り当てを実行すると考えるのは正しいですか?また、これはnull合体演算子の悪い使い方ですか?
生成されたコードの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はその違いさえも取り除くのに十分賢いかもしれません!
これはnull合体演算子の悪い使い方ではないと思います。コードを読むとき、それは可能な限り短く簡潔であり、コードの意図は明白です。
このようにnull合体演算子を使用すると、常に割り当てが得られるのは正しいですが、私はそれについて心配する必要はありません。(そして、それが本当にパフォーマンスの問題であることが判明した場合、あなたはすでにそれを修正する方法を知っています)。
あなたは、最初の行が常に割り当てを行うという点で正しいです。コードが頻繁に実行されない限り、私はそれについて心配することはありません。