2009-04-24 10 views
2

驚くべきことに、コードは成功しません。この場合、NULL値の型が等しくないのはなぜですか?

int? n1 = null; 
int? n2 = null; 
Assert.IsTrue(n1 <= n2); // Fails here 

あなたはその理由を知っていますか?

+1

あなたの例は、null(null> = null)がfalseであることを尋ねる方が良いかもしれません。nullableをnullに比較する方法について議論する必要があるので、これはnullです。 – meandmycode

+0

meandmycode、良い点。私は(null> = null)がfalseであることに気付かなかった。しかし、より深く見ると、CLRはnullの可能な式を(null> = null)にします。 – Vadim

答えて

6

を倍のロジックを挑みます。私は「ヌルは価値ではない」ということを覚えておくのが最も理にかなっています。 nullは値ではないため、操作はできません。したがって、 "1 > null"と "1 < null"のようなものはどちらも真です。ここで

は、詳細なガイドです:http://msdn.microsoft.com/en-us/library/2cf62fcy.aspx

あなたが値としてnullを扱いたいならば、あなたはデフォルト値とヌル同一視するGetValueOrDefaultMethod()を使用することができます。たとえば、

Assert.IsTrue(n1.GetValueOrDefault() <= n2.GetValueOrDefault()); // True 

これは少し冗長ですが、これで完了します。

4

これは入力ミスであり、 "=="は "< ="ではないか、またはnullがどのように機能するか誤解しています。

ほとんどすべての言語(c#を含む)では、nullのデフォルトの法的操作は、それ以外のものがあるかどうかをチェックすることです(.Net ==はデフォルトで参照の等価性です)。

< =と> =意味がありません(彼らがした場合、彼らは非常に奇妙な行動を持っているように)

いくつかの言語(SQLは、おそらく最もよく知られているもの)が作成する「標準」等価演算子の使用を禁止しますこれはさらにはっきりしています。 SQLの場合null == nullは真ではなく、準拠しているサーバーはリテラルでこれを実行しようとしたときにクエリを拒否します。

C#は、ヌル値のテストがそのビットがゼロであることに基づいている(物事はやや複雑ですが、実際には起こっていることです)、遺産と同じルートをとっています。そのようなリファレンスタイプは本当にヌル(Nullable<T>はそれのように見えるように舞台裏で多くの魔法を持っているが実際にはフードの下にあるはnullではない)です。これは、参照等価セマンティクスがヌルセマンティクスにうまく従うことを意味し、したがって、==ヌルが許可されます。

他の言語では、何かがnullになる可能性があるSQLのようにnullを実装しているため、何かのNULL値がNullableのように外部に格納されていなければなりません。第一の関心事とヌルは本当に特別なのではなく、特定の種類の特殊なケースであることが可能ではない。ヌルのspecialnessの詳細情報については にThis question has a list of such languages

を見てみましょうほとんどの参照型は=> =や<を定義しません==と< =の間の切断では問題はほとんどありません(通常は==に対して何かが真であれば、< =と> = asの場合に真となります)よく)。

+2

これはC#とSQLのどちらが混乱するかです。 C#のようなプログラミング言語では、null == null。しかし、SQLでは、NULL = NULL、NULL!= NULLなどの何も当てはまりません。 – n8wrl

+0

これは誤字ではありません。私は "<="を意味しました。 – Vadim

+1

はい。ヌルは「特別」です。 http://stackoverflow.com/questions/75267/in-how-many-languages-is-null-not-equal-to-anything-not-even-null/75314#75314 –

0

null値の型はSystem.Nullableオブジェクトにラップされるため、int値を比較しないため、参照を比較します。値を比較するには、あなたがそのようにそれを行う必要があります。

Assert.IsTrue(n1.Value <= n2.Value); 

私はblogにNULL可能について少し書きました。

編集: あなたのケースでは、n1とn2がヌルなので、値を比較することさえできません。

+0

これはどのように優れていますか?それはちょうど 'NullReferenceException'をスローします... –

+0

これらの参照の1つがnullの場合は、何をしたいかによって異なります。ヌルも有効ではないと仮定してみましょう。したがって、次のようになります。 Assert.IsTrue(n1!= null && n2!= null && n1.Value <= n2.Value); 私の例では、これらの参照のいずれかがnullの場合、例外がスローされません。 – Enyra

4

あなたはこの試みることができます。多くの場合、C#(およびVB.Net)にNULL NULL可能値でブール論理を使用して

int? n1 = null; 
int? n2 = null; 

// Test for equality 
Assert.IsTrue((n1.HasValue && n2.HasValue && n1.Value == n2.Value) || (!n1.HasValue && !n2.HasValue)); 

// Test for less than or equal to 
Assert.IsTrue(n1.HasValue && n2.HasValue && n1.Value <= n2.Value); 
+0

元のテストは:n1.Value <= n2.Value –

+0

コードを更新しました。ありがとう。 –

関連する問題