可空類型
實值型別是不可以為null的[即不可為空白值], 假如我們想讓它為null呢[比如它對映這資料庫中的某個表的某個欄位,但是這個欄位是null]。 自己實現的話,簡單的寫一個類,有一個實值型別的欄位,檢查該欄位是否初始化,是的話返回該值,否的話返回null。 假如是在C#1.0時,那麼每個實值型別都要寫這麼一份代碼了。C#2.0有了泛型的支援,所以我們可以定義一個泛型版的。 幸運的是C#2.0帶來了一個新的類型[System.Nullable<T>]幫我們實現了,T就是需要傳入的類型[約束為實值型別]. 比如:
Nullable<int> i=null; //簡寫?int? i=null;
下面是System.Nullable<T>泛型類原型:
1 [Serializable]//表示了序列化 2 public struct Nullable<T> where T : struct 3 { 4 //構造器,初始化型別參數T 5 public Nullable(T value); 6 //重載類型轉換操作符<顯示轉換:int i=(int)Nullable<int>類型變數> 7 public static explicit operator T(T? value); 8 //重載類型轉換操作符<隱式轉換:int? i=int類型變數> 9 public static implicit operator T?(T value);10 //判斷是否是null,11 public bool HasValue { get; }12 //如果不是null,取得值13 public T Value { get; }14 //重寫Equals15 public override bool Equals(object other);16 //重寫GetHashCode17 public override int GetHashCode();18 //如果HasValue屬性為true,返回Value屬性的值19 //否則返回當前 Nullable<T> 對象<類型是T>的預設值20 //即使 HasValue屬性為false,GetValueOrDefault方法也會返回一個值21 //(這與 Value 屬性不同,該屬性將引發異常)。22 public T GetValueOrDefault();23 //同上,參數是指定的預設值,如果int? i=null;24 //int j=i.GetValueOrDefault(10);則j的值為1025 public T GetValueOrDefault(T defaultValue);26 //重寫ToString27 public override string ToString();28 }
各個方法使用DEMO:
static void Main(){ Nullable<int> i = null; int l = i.GetValueOrDefault();//l=0 int n = i.GetValueOrDefault(10);//j=10 int h = i.HasValue ? i.Value : default(int);//h=0 int m = 100; i = m;//隱式轉換 m = (int)i;//顯示轉換 Console.WriteLine(i.Equals(m));//true Console.WriteLine(i.GetType());//System.Int32 Console.WriteLine(i.ToString());//100}
現在做些運算:
static void Main(){ Nullable<int> i = 1; int? j = 2; //執行運算之前會先調用HasValue屬性 int l = (int)(i + j); Console.WriteLine(l);//3 i = null; //拋出異常System.InvalidOperationException //其中一個為null則結果就為null,所以null無法轉換為int int n = (int)(i + j); Console.WriteLine(n);}
它的這些運算還是蠻繁瑣的,先檢查是否為null,如果都不是null,再取得各自的值在運算,否則返回null。 不是迫不得已的情況下最好不使用[效率不怎麼好]。
靜態類
靜態類是只用於包含靜態成員,它既不能執行個體化,也不能被繼承。 它相當於一個sealed abstract類[查看IL代碼實際上靜態類就是被標識為sealed和abstract]。 相當於提供一些功能性的全域函數[C#不支援全域函數,但是CLR支援,IL支援,這算是一種變相的實現全域函數吧]。
靜態類不能有執行個體構造器;
靜態類不能有任何執行個體成員;
靜態類上不能使用abstract或sealed修飾符;
靜態類預設繼承自System.Object根類,不能顯式指定任何其他基類[實際上也沒有什麼意義的];
靜態類不能指定任何介面實現。;
靜態類的成員不能有protected 或 protected internal訪問保護修飾符[這些都是供子類訪問的,但是靜態類不允許被繼承,所以你用這些存取修飾詞沒有任何意義]。