web-dev-qa-db-ja.com

ヌル結合演算子を使用したヌルオブジェクトのインスタンス化

次の典型的なシナリオを検討してください。

if(myObject == null) {
    myObject = new myClass();
}

私は、null-coalescing演算子を使用した次の置換についてどう考えているのでしょうか。

myObject = myObject ?? new myClass();

2番目のフォームを使用する必要があるかどうかわかりません。いい速記のようですがmyObject = myObject最初の構文は、コードの匂いのように見えるかもしれません。

これはやるべき合理的なことですか、それとも私が見逃しているより優れた速記がありますか?それとも、「3行です。やり直してください!」

編集:言及されたように、おそらくこれを典型的なシナリオと呼ぶことは誇張のようなものです。私は通常、まだデータが入力されているかどうかわからない子参照型プロパティを持つデータベースからエンティティを取得しているときに、この状況に遭遇します。

myClass myObject = myClassService.getById(id);
myObject.myChildObject = myObject.myChildObject ?? new myChildClass();
12
grin0048

私は常にnull合体演算子を使用しています。私はそれの簡潔さが好きです。

この演算子は、本質的に三項演算子(A?B:C)に似ていることがわかりました。読み方が自然になる前に少し練習する必要がありますが、慣れると、長いバージョンより読みやすさが向上するように感じます。

また、説明する状況は、オペレーターが役立つ1つのシナリオにすぎません。次のような構成を置き換えるのも便利です。

if (value != null)
{
    return value;
}
else
{ 
    return otherValue;
}

または

return value != null ? value : otherValue;

return value ?? otherValue;
16
17 of 26

特に私が疑問に思っているのは、nullでない限り、演算子を使用してオブジェクトをそれ自体に設定することです。

_?? operator_は、null結合演算子と呼ばれ、null許容値型または参照型のデフォルト値を定義するために使用されます。オペランドがnullでない場合は、左側のオペランドを返します。それ以外の場合は、正しいオペランドを返します。

myObject = myObject ?? new myObject();-_instantiate default value of object_

Null結合演算子に関する詳細とコードサンプル- MSDN記事

_more than nullable_条件をチェックする場合、alternativeとして、Ternary演算子を使用できます。

三項演算子

?:演算子も確認できます。これは3項演算子または条件付き演算子と呼ばれます。条件演算子(?:)は、ブール式の値に応じて2つの値のいずれかを返します。

Null許容型には値を含めることができますが、未定義にすることもできます。 ??演算子は、null許容型がnull不可型に割り当てられたときに返されるデフォルト値を定義します。 ??を使用せずに、null許容値型をnull不可値型に割り当てようとした場合演算子を使用すると、コンパイル時エラーが発生します。キャストを使用し、null許容値の型が現在未定義の場合、InvalidOperationException例外がスローされます。

MSDN-?:演算子(C#リファレンス) のコード例:

_int? input = Convert.ToInt32(Console.ReadLine());
string classify;

// ?: conditional operator.
classify = (input.HasValue) ? ((input < 0) ? "negative" : "positive") : "undefined";
_
2
Yusubov

私はそのシナリオが典型的である(または少なくともそうあるべきである)とは思いません。

一部のフィールドのデフォルト値をnullにしない場合は、フィールド初期化子に設定します。

myClass myObject = new myClass();

または、初期化がより複雑な場合は、コンストラクターで設定します。

実際に必要な場合にのみmyClassを作成する場合(たとえば、作成に時間がかかるため)、 Lazy<T> を使用できます。

Lazy<myClass> myObject = new Lazy<myClass>();

(これはデフォルトのコンストラクターを呼び出します。初期化がより複雑な場合は、myClassを作成するラムダをLazy<T>コンストラクターに渡します。)

値にアクセスするには、myObject.Valueを使用します。これは、myObject.Valueに初めてアクセスする場合に初期化を呼び出します。

2
svick

私は特に??オプションのメソッドパラメータと組み合わせて。オーバーロードの必要性を制限し、物事に価値があることを確認します。

public void DoSomething (MyClass thing1 = null) {
    thing1 = thing1 ?? new MyClass();
}
1
radarbob