3

私が使う ??私のコードでは非常に重く演算子です。しかし、今日、私は質問に出くわしました。

ここで私が使用するコードは?? オペレーター

private List<string> _names;
public List<string> Names
{
    get { return _names ?? (_names = new List<string>()); }
}

しかし、いくつかの場所では、このコードも見ました。

private List<string> _names;
public List<string> Names
{
    get { return _names ?? new List<string>(); }
}

これらのコードの実際の違いは何ですか。1 つは _names = new List() を割り当て、もう 1 つは new List() を実行しているだけです。

4

4 に答える 4

6

私が見る唯一の違いは、最初のケースでは変数 _names に新しい空のリストが含まれ、2番目のケースでは含まれないことです。どちらの場合も、返される値は同じです。

于 2013-09-10T05:41:41.447 に答える
3

2 番目のケースでは を割り当てず_names、 null のnew List<string>()場合_namesは呼び出すたびにNamesを作成しますnew List<string>()が、最初のケースではnew List<string>()作成します。

于 2013-09-10T05:40:43.237 に答える
2

どちらの場合も同じ値を返しますが、違いは、プライベート関数の任意の場所で _names にアクセスしている場合、最初のケースでは _names が空のリストを持ち、2 番目のケースでは null 値を持つことです。したがって、最初の実装はコーディング標準に従って正しいですが、2 番目のケースでは null 例外の問題に直面する可能性があります。

于 2013-09-10T06:10:28.937 に答える
2

他の人が言ったように、違いは_namesプロパティが取得された後のフィールドの状態です。

ケース1

get { return _names ?? (_names = new List<string>()); }

_namesが null の場合、新しいList<string>が作成されて割り当てられます。その後、プロパティを取得するたびに、Names作成されたばかりのリストが返されます。

ケース 2

get { return _names ?? new List<string>(); }

_namesnull の場合、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 を返すと、そのブロック全体がスキップされます。ただし、毎回新しいリストを返すため、ループ全体を実行して本質的に何もしないだけでなく、反復ごとに新しいリストをインスタンス化しています! これは、特定の条件下では非常に高価になる可能性があります。

于 2013-09-10T06:29:44.257 に答える