次のコード行に出くわしました:
FormsAuth = formsAuth ?? new FormsAuthenticationWrapper();
2 つのクエスチョン マークは何を意味していますか。それはある種の三項演算子ですか? Googleで検索するのは難しいです。
次のコード行に出くわしました:
FormsAuth = formsAuth ?? new FormsAuthenticationWrapper();
2 つのクエスチョン マークは何を意味していますか。それはある種の三項演算子ですか? Googleで検索するのは難しいです。
これは null 合体演算子であり、三項 (immediate-if) 演算子とよく似ています。こちらもご覧ください?? オペレーター - MSDN .
FormsAuth = formsAuth ?? new FormsAuthenticationWrapper();
次のように展開されます。
FormsAuth = formsAuth != null ? formsAuth : new FormsAuthenticationWrapper();
これはさらに次のように拡張されます。
if(formsAuth != null)
FormsAuth = formsAuth;
else
FormsAuth = new FormsAuthenticationWrapper();
英語では、「左側にあるものが null でない場合はそれを使用し、そうでない場合は右側にあるものを使用する」という意味です。
これらを連続していくつでも使用できることに注意してください。次のステートメントは、最初の非 nullAnswer#
を割り当てますAnswer
(すべての Answers が null の場合Answer
は null です)。
string Answer = Answer1 ?? Answer2 ?? Answer3 ?? Answer4;
また、上記の展開は概念的に同等ですが、各式の結果は一度だけ評価されることに注意してください。これは、たとえば、式が副作用のあるメソッド呼び出しである場合に重要です。(これを指摘してくれた@Joeyの功績。)
他の誰もまだ魔法の言葉を言っていないという理由だけで、それはnull 合体 operatorです。これは、 C# 3.0 言語仕様のセクション 7.12 で定義されています。
これは非常に便利です。特に、式で複数回使用された場合に機能するためです。次の形式の式:
a ?? b ?? c ?? d
a
null 以外の場合は式の結果を返します。それ以外の場合は try 、b
そうでない場合は try を返します。あらゆる点で短絡します。c
d
また、 の型がd
null 非許容の場合、式全体の型も null 非許容です。
null 合体演算子です。
http://msdn.microsoft.com/en-us/library/ms173224.aspx
はい、それが何と呼ばれているかを知らない限り、検索することはほとんど不可能です! :-)
編集:そして、これは別の質問のクールな機能です。それらを連鎖させることができます。
皆さん、ありがとうございます。MSDN サイトで見つけた最も簡潔な説明を次に示します。
// y = x, unless x is null, in which case y = -1.
int y = x ?? -1;
2 つの疑問符 (??) は、それが Coalescing オペレーターであることを示します。
合体演算子は、チェーンから最初の非 NULL 値を返します。このyoutube ビデオでは、実際にすべてを実演しています。
しかし、ビデオが言っていることにさらに付け加えさせてください。
合体の英語の意味を見ると、「一緒に固める」と書かれています。たとえば、以下は 4 つの文字列を連結する単純な合体コードです。
そのため、null 以外の値を持つ文字列が見つかるまで、 if str1
isnull
が試行されstr2
、 if str2
isnull
が試行されます。str3
string final = str1 ?? str2 ?? str3 ?? str4;
簡単に言えば、合体演算子は、チェーンから最初の非 NULL 値を返します。
??
値がnullの場合にnull許容型の値を提供するためにあります。したがって、formsAuth が null の場合、新しい FormsAuthenticationWrapper() が返されます。
三項演算子の省略形です。
FormsAuth = (formsAuth != null) ? formsAuth : new FormsAuthenticationWrapper();
または、三項をしない人のために:
if (formsAuth != null)
{
FormsAuth = formsAuth;
}
else
{
FormsAuth = new FormsAuthenticationWrapper();
}
Ruby に精通している場合、Ruby は||=
C# に似ているように思え??
ます。ここにいくつかのルビーがあります:
irb(main):001:0> str1 = nil
=> nil
irb(main):002:0> str1 ||= "new value"
=> "new value"
irb(main):003:0> str2 = "old value"
=> "old value"
irb(main):004:0> str2 ||= "another new value"
=> "old value"
irb(main):005:0> str1
=> "new value"
irb(main):006:0> str2
=> "old value"
そして C# では:
string str1 = null;
str1 = str1 ?? "new value";
string str2 = "old value";
str2 = str2 ?? "another new value";
合体演算子
それは同等です
FormsAuth = formsAUth == null ? new FormsAuthenticationWrapper() : formsAuth
「null合体演算子」(??)である多くの回答で正しく指摘されているように、そのいとこである「Null条件演算子」(?.または?[)をチェックすることもできます。多くの場合、??と組み合わせて使用されます。
メンバー アクセス ( ?. ) またはインデックス ( ?[ ) 操作を実行する前に null をテストするために使用されます。これらの演算子を使用すると、null チェックを処理するためのコードの記述を減らすことができます。特に、データ構造に降りる場合に役立ちます。
例えば:
// if 'customers' or 'Order' property or 'Price' property is null,
// dollarAmount will be 0
// otherwise dollarAmount will be equal to 'customers.Order.Price'
int dollarAmount = customers?.Order?.Price ?? 0;
?なしの古い方法。そして?? これを行うことは
int dollarAmount = customers != null
&& customers.Order!=null
&& customers.Order.Price!=null
? customers.Order.Price : 0;
これはより冗長で面倒です。
あなたの娯楽のためだけに(あなたがすべてC#の人であることを知っています;-)。
私は、それが何年も前から存在している Smalltalk に端を発していると思います。そこでは次のように定義されています。
オブジェクト内:
? anArgument
^ self
UndefinedObject (別名 nil のクラス):
? anArgument
^ anArgument
これには、評価版 (?) と非評価版 (??) の両方があります。
これは、遅延初期化されたプライベート (インスタンス) 変数の getter メソッドでよく見られ、本当に必要になるまで nil のままです。
合体を使用して値を取得する例のいくつかは非効率的です。
あなたが本当に欲しいのは:
return _formsAuthWrapper = _formsAuthWrapper ?? new FormsAuthenticationWrapper();
また
return _formsAuthWrapper ?? (_formsAuthWrapper = new FormsAuthenticationWrapper());
これにより、オブジェクトが毎回再作成されるのを防ぎます。プライベート変数が null のままで、リクエストごとに新しいオブジェクトが作成される代わりに、これにより、新しいオブジェクトが作成された場合にプライベート変数が確実に割り当てられます。