程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> C#中奇妙的函數—5. Nullable 靜態類

C#中奇妙的函數—5. Nullable 靜態類

編輯:C#入門知識

前段時間忙於各處奔波沒有寫博,今天想和大家再來看看一個奇妙的函數。

首先假設你不得不處理一些已有的代碼,裡面用到了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)”

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved