令人惊讶的是,下面的代码不会成功。
int? n1 = null;
int? n2 = null;
Assert.IsTrue(n1 <= n2); // Fails here
你知道为什么吗?
答案 0 :(得分:6)
在C#(和VB.Net)中使用具有空可空值的布尔逻辑通常会违反逻辑。我发现理解它的最好方法是记住“null不是一个值”。因为null不是值,所以无法对其执行任何操作。因此,“1 > null
”和“1 < null
”之类的内容都是正确的。
以下是详细指南:http://msdn.microsoft.com/en-us/library/2cf62fcy.aspx
如果您确实希望将null视为值,则可以使用GetValueOrDefaultMethod()将null与默认值相等。例如
Assert.IsTrue(n1.GetValueOrDefault() <= n2.GetValueOrDefault()); // True
这有点冗长,但它会完成工作。
答案 1 :(得分:4)
这是一个拼写错误,你的意思是“==”而不是“&lt; =”或者你误解了空值是如何工作的。
在几乎所有语言(包括c#)中,null的唯一默认合法操作是检查其他内容是否等于它(在.Net ==默认为引用相等)。
&lt; =和&gt; =没有意义(如果他们这样做会有非常奇怪的行为)
某些语言(SQL可能是最知名的)不允许使用“标准”等式运算符来使其更加清晰。在SQL null == null不是真的,并且兼容的服务器将拒绝您尝试通过文字执行此操作的查询。
C#采用与其遗产相同的路线(C风格命令式语言),其中对空值的测试基于测试其中的位为零(事情变得稍微复杂但从根本上说是正在发生的事情)。因此,只有引用类型才能真正为空(Nullable<T>
在幕后有很多魔法使它看起来像它,但实际上它是不是空的)。这意味着引用相等语义很好地遵循null语义,因此允许== null。
其他语言以不同的方式实现null(例如SQL,其中任何东西都可以为null,因此某些东西的'nullness'必须存储在它之外(很像Nullable)。这意味着传统的平等使用不需要作为主要关注点,null可以是真正特殊的,而不是某些类型的特殊情况。 有关null特殊性的更多信息,请查看This question has a list of such languages
大多数引用类型都没有定义一个&gt; =或&lt; =运算符,所以在实践中几乎没有问题,= =和&lt; =之间的断开连接(通常如果某些事情对于==是真的,那么它将是真的&lt; =和&gt; =以及。)
答案 2 :(得分:4)
你可以试试这个:
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);
答案 3 :(得分:0)
Nullable类型被包装到System.Nullable对象中,所以你不比较int值,你比较引用。要比较这些值,你需要这样做:
Assert.IsTrue(n1.Value <= n2.Value);
我在blog上写了一篇关于可空的内容。
编辑: 但在你的情况下,n1和n2为空,所以你甚至无法比较这些值。