1868

次のコード行に出くわしました:

FormsAuth = formsAuth ?? new FormsAuthenticationWrapper();

2 つのクエスチョン マークは何を意味していますか。それはある種の三項演算子ですか? Googleで検索するのは難しいです。

4

19 に答える 19

2454

これは 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の功績。)

于 2009-01-15T14:04:33.797 に答える
310

他の誰もまだ魔法の言葉を言っていないという理由だけで、それはnull 合体 operatorです。これは、 C# 3.0 言語仕様のセクション 7.12 で定義されています。

これは非常に便利です。特に、式で複数回使用された場合に機能するためです。次の形式の式:

a ?? b ?? c ?? d

anull 以外の場合は式の結果を返します。それ以外の場合は try 、bそうでない場合は try を返します。あらゆる点で短絡します。cd

また、 の型がdnull 非許容の場合、式全体の型も null 非許容です。

于 2009-01-15T14:07:52.727 に答える
76

null 合体演算子です。

http://msdn.microsoft.com/en-us/library/ms173224.aspx

はい、それが何と呼ばれているかを知らない限り、検索することはほとんど不可能です! :-)

編集:そして、これは別の質問のクールな機能です。それらを連鎖させることができます。

C# の隠れた機能?

于 2009-01-15T14:05:32.733 に答える
34

皆さん、ありがとうございます。MSDN サイトで見つけた最も簡潔な説明を次に示します。

// y = x, unless x is null, in which case y = -1.
int y = x ?? -1;
于 2009-01-15T14:09:36.267 に答える
29

ここに画像の説明を入力

2 つの疑問符 (??) は、それが Coalescing オペレーターであることを示します。

合体演算子は、チェーンから最初の非 NULL 値を返します。このyoutube ビデオでは、実際にすべてを実演しています。

しかし、ビデオが言っていることにさらに付け加えさせてください。

合体の英語の意味を見ると、「一緒に固める」と書かれています。たとえば、以下は 4 つの文字列を連結する単純な合体コードです。

そのため、null 以外の値を持つ文字列が見つかるまで、 if str1isnullが試行されstr2、 if str2isnullが試行されます。str3

string final = str1 ?? str2 ?? str3 ?? str4;

簡単に言えば、合体演算子は、チェーンから最初の非 NULL 値を返します。

于 2013-12-16T10:30:05.330 に答える
24

??値がnullの場合にnull許容型の値を提供するためにあります。したがって、formsAuth が null の場合、新しい FormsAuthenticationWrapper() が返されます。

于 2009-01-15T14:05:07.913 に答える
16

三項演算子の省略形です。

FormsAuth = (formsAuth != null) ? formsAuth : new FormsAuthenticationWrapper();

または、三項をしない人のために:

if (formsAuth != null)
{
  FormsAuth = formsAuth;
}
else
{
  FormsAuth = new FormsAuthenticationWrapper();
}
于 2009-01-15T14:05:35.853 に答える
12

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";
于 2009-06-30T17:16:22.673 に答える
11

合体演算子

それは同等です

FormsAuth = formsAUth == null ? new FormsAuthenticationWrapper() : formsAuth
于 2009-01-15T14:05:52.373 に答える
11

「null合体演算子」(??)である多くの回答で正しく指摘されているように、そのいとこである「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; 

これはより冗長で面倒です。

于 2016-10-30T02:43:50.683 に答える
10

あなたの娯楽のためだけに(あなたがすべてC#の人であることを知っています;-)。

私は、それが何年も前から存在している Smalltalk に端を発していると思います。そこでは次のように定義されています。

オブジェクト内:

? anArgument
    ^ self

UndefinedObject (別名 nil のクラス):

? anArgument
    ^ anArgument

これには、評価版 (?) と非評価版 (??) の両方があります。
これは、遅延初期化されたプライベート (インスタンス) 変数の getter メソッドでよく見られ、本当に必要になるまで nil のままです。

于 2009-01-15T14:31:04.023 に答える
9

合体を使用して値を取得する例のいくつかは非効率的です。

あなたが本当に欲しいのは:

return _formsAuthWrapper = _formsAuthWrapper ?? new FormsAuthenticationWrapper();

また

return _formsAuthWrapper ?? (_formsAuthWrapper = new FormsAuthenticationWrapper());

これにより、オブジェクトが毎回再作成されるのを防ぎます。プライベート変数が null のままで、リクエストごとに新しいオブジェクトが作成される代わりに、これにより、新しいオブジェクトが作成された場合にプライベート変数が確実に割り当てられます。

于 2014-05-12T02:44:24.770 に答える