web-dev-qa-db-ja.com

==がnull値に対してtrueを返すのに、> =がfalseを返すのはなぜですか?

Int型の変数が2つありますか? (または、必要に応じてNullable <int>)。 2つの変数に対して大なり(> =)の比較を行いたかったのですが、結局のところ、両方の変数がnullの場合、これはfalseを返しますが、==演算子は明らかにtrueを返します。

> =演算子のセマンティック定義に「または」という単語が含まれているため、なぜそれが論理的であるのかを誰かが私に説明できますか?

78
Koen

この機能が元々C#2.0で設計されていたとき、この奇妙さについて大きな議論がありました。問題は、C#ユーザーがこれが意味のあることに完全に慣れていることです。

if(someReference == null)

Null許容値型に等式を拡張する場合、次の選択肢があります。

  1. ヌル可能平等は本当に持ち上げられたです。オペランドの一方または両方がnullの場合、結果はtrueでもfalseでもありませんが、nullです。この場合、次のいずれかを実行できます。

    • a)ifステートメントにはnull許容ブールではなくブールが必要なため、ifステートメントにnull許容値型が等しいことを違法にします。代わりに、nullと比較する場合は、全員にHasValueを使用するように要求します。これは冗長で苛立たしいものです。

    • b)nullをfalseに自動的に変換します。これの欠点は、x==null xがnullの場合、falseを返します。これは混乱を招き、参照型とのnull比較についての人々の理解に反します。

  2. ヌル可能平等は解除されません。 null許容の同等性はtrueまたはfalseのいずれかであり、nullとの比較はnullチェックです。これにより、null許容の等式はnull許容の不等式と矛盾します。

これらの選択はどれも明らかに正しくありません。それらはすべて長所と短所があります。たとえば、VBScriptは1bを選択します。多くの議論の末、C#設計チームは#2を選択しました。

95
Eric Lippert

なぜなら、平等は比較可能性とは別に定義されているからです。
テストできますx == null だが x > nullは無意味です。 C#では、常にfalseになります。

58
Henk Holterman

'> ='を説明する別の方法は、次のとおりです。等しいという言及はありません。不等式テストのオペランドの1つがNullになるとすぐに、結果も不明になります(nullになります)。ただし、両方のオペランドがNullであるかどうかを知りたい場合は、Null == Nullが妥当なテストです(結果はtrueになるはずです)。演算子の不等式部分を取り除くことは、すべての違いを生みます。

http://msdn.Microsoft.com/en-us/library/2cf62fcy.aspx#sectionToggle4 の次のコード例は、C#がNullを処理する方法をまとめたものです。

int? num1 = 10;   
int? num2 = null;   
if (num1 >= num2)   
{   
    Console.WriteLine("num1 is greater than or equal to num2");   
}   
else   
{   
    // This clause is selected, but num1 is not less than num2.   
    Console.WriteLine("num1 >= num2 returned false (but num1 < num2 also is false)");   
}   

if (num1 < num2)   
{   
    Console.WriteLine("num1 is less than num2");   
}   
else   
{   
    // The else clause is selected again, but num1 is not greater than   
    // or equal to num2.   
    Console.WriteLine("num1 < num2 returned false (but num1 >= num2 also is false)");   
}   

if (num1 != num2)   
{   
    // This comparison is true, num1 and num2 are not equal.   
    Console.WriteLine("Finally, num1 != num2 returns true!");   
}   

// Change the value of num1, so that both num1 and num2 are null.   
num1 = null;   
if (num1 == num2)   
{   
    // The equality comparison returns true when both operands are null.   
    Console.WriteLine("num1 == num2 returns true when the value of each is null");   
}   

/* Output:   
 * num1 >= num2 returned false (but num1 < num2 also is false)   
 * num1 < num2 returned false (but num1 >= num2 also is false)   
 * Finally, num1 != num2 returns true!   
 * num1 == num2 returns true when the value of each is null   
 */   
11
NealB

>=は数値で動作します。どのnullはそうではありません。

あなたは 過負荷>=演算子を使用して特定のタイプに必要なものを提供します。

2
Aaron McIver

デフォルトでは、intをnullにすることはできず、その値は0に設定されるため、intタイプ用に作成された>および<の演算子は、valuesではなくnullsで機能することを想定しています。

nullable intおよびless <演算子を使用してgreater >を処理するいくつかの方法を書いた同様の質問に対する私の回答を参照してください https://stackoverflow.com/a/51507612/700376

0
Mayer Spitzer

NULLは、ゼロ(数値または2進値)、長さゼロのストリング、またはブランク(文字値)ではありません。したがって、比較演算子は常にfalseを返します。 詳細はこちら

0
Sam

> =は、その特定の明確に定義された方法で使用される場合にのみ「以上」を意味します。オーバーロードされた演算子を持つクラスで使用される場合、それはクラス開発者が意味したいことを意味します。文字列のようなクラスに適用される場合、「同じかそれ以上にソートする」ことを意味する場合もあれば、「同じ長さ以上」を意味する場合もあります。

0
Sparr

どのような価値を期待しますか?

null == null tr​​ue

null> = null false

null> null false

null <= null false

null <null false

null!= null false

1 == null false

1> = null false

1> null false

1 <= null false

1 <null false

1!= null tr​​ue別名!(1 == null)

0
Bengie