2017-06-07 28 views
4

なぜ次のコードがfalseを返すのですか?C#coalesce演算子

public static void Main() 
{ 
    bool? someCondition = true; 
    bool someConditionOverride = false; 


    bool? result = someCondition ?? someConditionOverride ? false : (bool?)null; 

    Console.WriteLine(result); 
} 

私はsomeConditionnullないと??オペレータがtrueを返しますので、結果は、trueなりますexprectingました。しかし右のオペランドが最初に計算され、左の部分が単に無視されるように見えます。ブラケットを追加

は混乱修正:

bool? result = someCondition ?? (someConditionOverride ? false : (bool?)null) 

を、結果はtrueになります。しかし、私はまだ最初の例では左の部分が無視されていたのは不思議です。

+0

[C#null-coalescing(??)演算子の演算子の優先順位は何ですか?](https://stackoverflow.com/questions/511093/what-is-the-operator-precedence-of-c-sharp- null-coalescing-operator)はそれを説明します...恐らく重複として使用することができます。 –

+0

これは実際には本当に良い質問 –

+0

単に式を読んだだけで、 '??'が最初に評価され、 'false'が返されると考えられます。私は、 '?:'が ' - 'より優先されるとは思わないのと同じように、 '?:'の優先順位が高くなるとは思わないでしょう。 –

答えて

17

"左の部分は単純に無視されます"それは本当にどれくらい可能性があると思いますか?

bool? result = (someCondition ?? someConditionOverride) 
        ? false 
        : (bool?)null; 

someConditionがnullでなく、それは本当である:

演算子の優先順位は、あなたの最初のバージョンはそうのように解析されることを指示します。したがって、この表現はtrueとして評価されます。

(someCondition ?? someConditionOverride) 

だから我々は?ブランチを取得し、式全体は、あなたがそれを告げただけのように、falseを返します。

追加した角括弧を追加すると、式の意味が完全に変更されます。それはあなたの混乱を限られた意味で修正します。あなたの本来の意図に沿った表現の実際の意味を持ちます。コンパイラは決して混乱しません。 C#では、コンパイラはを混乱させます。

私自身の混乱を減らすために、私はオペレータの優先順位に頼ることはありません。私はすべてを括弧でくくっている。もし私がその言語を設計していれば、文法はそれを必要とするでしょう(エリックがそれを説明してくれれば、それはなぜ実際にはあまり良いアイデアではないのか、私には分かります。

UPDATE:予測検証:エリックはによって来て、あまりにも多くの人々はそれがとんでもないa + b * cを括弧する必要が見つけるだろう、とあなたは、例外を定義するための合理的な方法がないことを許可した場合と述べました。まあ、もし彼らがすべてをかっこにすることを余儀なくされることを許さないなら、彼らはそうするべきではないと思う。

+4

"C#ではコンパイラがあなたを混乱させます" - それだけで+1! –

+1

私は "私はすべてをかっこにします。私がその言語を設計していれば、文法はそれを必要とします。"それは物語の本質です。 – Artem

+0

@Artemなぜ '?:'は '??'より優先度が高くなりますか?私は演算子が左から右へ –