他の人が言ったように、違いは_names
プロパティが取得された後のフィールドの状態です。
ケース1
get { return _names ?? (_names = new List<string>()); }
_names
が null の場合、新しいList<string>
が作成されて割り当てられます。その後、プロパティを取得するたびに、Names
作成されたばかりのリストが返されます。
ケース 2
get { return _names ?? new List<string>(); }
_names
null の場合、newList<string>
が返されます。ケース 1 とは対照的に、それは何にも割り当てられません。これは、を取得するたびNames
に、新しいリストが作成されて返されることを意味します。
そうは言っても、このコードの両方のバージョンには細心の注意を払う必要があります。に値を割り当てることは、get
必ずしも良いことではありません。プロパティ値を遅延してインスタンス化するのは便利で、クラスを使用するのが自分だけの場合には受け入れられるかもしれませんが、スタイルは良くありません。クラス外のユーザーは、get
が何かを設定することを期待しません...それがset
プロパティの一部です。_names
長期的には、デフォルトのコンストラクターでそれを返してインスタンス化する方が常に良いでしょう。次に、コードが何をしているのかが明確になり、null 以外のプロパティ値が保証されます。
2 番目のケースでは、null を返し、ユーザーがそれを処理できるようにする方がはるかに優れています。次のケースを考えてみましょう。items
はオブジェクトの大規模なコレクションで、それぞれにプロパティが含まれてNames
おり、何らかの理由でNames
常に null です。
foreach (var item in items.Where(x => x.Names != null)) {
Console.WriteLine(String.Join(", ", item.Names));
}
単純に null を返すと、そのブロック全体がスキップされます。ただし、毎回新しいリストを返すため、ループ全体を実行して本質的に何もしないだけでなく、反復ごとに新しいリストをインスタンス化しています! これは、特定の条件下では非常に高価になる可能性があります。