当前位置:编程学习 > C#/ASP.NET >>

C#中奇妙的函数—5. Nullable 静态类

前段时间忙于各处奔波没有写博,今天想和大家再来看看一个奇妙的函数。

首先假设你不得不处理一些已有的代码,里面用到了nullable(可空值类型)的变量, 你必须要用这变量与不可空变量比较.

使用  <, >, <=, >= 来比较 nullable 值
看下面的代码:

1: int? x = null;2:  3: if (x < 100)4: {5:     Console.WriteLine("是, {0} 小于 100.",6:                       x.HasValue ? x.ToString() : "null");7: }8: else9: {0:     Console.WriteLine("否, {0} 不小于 100.",1:                       x.HasValue ? x.ToString() : "null");2: }
有人可能认为要么结果为“是”, 要么 抛出 NullReferenceException, 对吗? 因为一个null的整型在我们理解中是比100小,但是运行的结果为“否”!

 

下面的例子更加的令人费解,因为结果也为“否”:

1: int? x = null;2:  3: if (x < int.MaxValue)4: {5:     // ...6: }
那么,我们说 null 小于所有的有效整型, 对吗? 如果对的话,你怎么看这段代码:

1: int? x = null; 2:   3: // 等等,X 不小于MinValue? 4: if (x < int.MinValue) 5: { 6:     // ... 7: }
如果我们使用大于符号判断时:

1: int? x = null;  2:    3: // x 也不大于MinValue….  4: if (x > int.MinValue)  5: {  6:     // ...  7: }
结果使用四种比较运算符 ( <, >, <=, >= ) 全都返回否。 这个同样适用于其他有这样运算符定义的类型: short,  float, double, DateTime, TimeSpan。


在.net 机制下 null 不是一个大数值,也不是小数值,比较时也不会发生异常。

 

更奇怪的事:

1: DateTime? x = null; 2: DateTime? y = null; 3:   4: if (x <= y) 5: { 6:     Console.WriteLine("你觉得他们相等吗?"); 7: } 8: else 9: {10:     Console.WriteLine("结果不是:<=, <, >, >= 根本不适用于null.");11: }
再看看下面的代码:

1: int? x = null;  2: int? y = 100;  3:    4: if (x < y)  5: {  6:     Console.WriteLine("X 小于 Y");  7: }  8: else if (x > y)  9: { 10:     Console.WriteLine("X 大于 Y"); 11: } 12: else 13: { 14:     // 这个才是我们得到的结果 15:     Console.WriteLine("X 等于 Y"); 16: }。。
解决方案: nullable 静态类
因此,我们已经看到,<,<=,>,和>= 有一些有趣的意外行为。

但是,如果我们把null 看成是一个非常低的值应该怎么办?

例如,如果我们要排序一个列表。在列表中显示的是公司当前的股票价格:

 

代号      描述                                  价位
------      -----------------------    ----------
ABCZ        Apples and Oranges Inc     n/a
XYZP        Zippers and Buttons Inc    1.57
AZAZ        Carrots and Turnips Inc    23.13

 比较运算符不适用于 null,因此,我们不得不做一些非常复杂的逻辑,如:

1: if (x.HasValue) 2: { 3:     if (y.HasValue) 4:     { 5:         if (x < y) 6:         { 7:             Console.WriteLine("x < y"); 8:         } 9:         else if (x > y) 0:         { 1:             Console.WriteLine("x > y"); 2:         } 3:         else 4:         { 5:             Console.WriteLine("x == y"); 6:         } 7:     } 8:     else 9:     { 0:         Console.WriteLine("x > y 因为 y 是 null, x 不是"); 1:     } 2: } 3: else if (y.HasValue) 4: { 5:     Console.WriteLine("x < y 因为 x 是 null, y 不是"); 6: } 7: else 8: { 9:     Console.WriteLine("x == y 因为 都为 null"); 0: }
 

我们也许可以简化这个函数,但它仍然是相当凌乱!但有一个更清洁的方式做到这一点,

如果你在MSDN上 读到 IComparer如何工作:

当使用 IComparable 时,允许将 Nothing 与任何类型进行比较,而且不会生成异常。 排序时,Nothing 被视为小于任何其他对象。
所以,我们可以改变我们的逻辑使用Nullable.Compare <T>( )静态方法 :

1: int? x = null; 2: int? y = 100; 3:   4: if (Nullable.Compare(x, y) < 0) 5: { 6:     //  7:     Console.WriteLine("x < y"); 8: } 9: else if (Nullable.Compare(x, y) > 0) 0: { 1:     Console.WriteLine("x > y"); 2: } 3: else 4: { 5:     Console.WriteLine("x == y"); 6: }
摘要
所以,当比较两个数值而其中之一可能是一个null 时,考虑使用System.Nullable.Compare <T>( )方法,而不是比较运算符 。它会将 null 当作比任何值都小,而且使用它可以避免一些逻辑一致性问题,象 < 返回 false,>= 返回 true 等 。

 本文出自“喜乐的ASP.NET(Alex Song)”

补充:软件开发 , C# ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,