天天看點

[C#2] 4-可空類型、靜态類1. 可空類型2. 靜态類

1. 可空類型

值類型是不可以為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     //重寫Equals
15     public override bool Equals(object other);
16     //重寫GetHashCode
17     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的值為10
25     public T GetValueOrDefault(T defaultValue);
26     //重寫ToString
27     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。 不是迫不得已的情況下最好不使用[效率不怎麼好]。

2. 靜态類

靜态類是隻用于包含靜态成員,它既不能執行個體化,也不能被繼承。 它相當于一個sealed abstract類[檢視IL代碼實際上靜态類就是被辨別為sealed和abstract]。 相當于提供一些功能性的全局函數[C#不支援全局函數,但是CLR支援,IL支援,這算是一種變相的實作全局函數吧]。

靜态類不能有執行個體構造器;

靜态類不能有任何執行個體成員;

靜态類上不能使用abstract或sealed修飾符;

靜态類預設繼承自System.Object根類,不能顯式指定任何其他基類[實際上也沒有什麼意義的];

靜态類不能指定任何接口實作。;

靜态類的成員不能有protected 或 protected internal通路保護修飾符[這些都是供子類通路的,但是靜态類不允許被繼承,是以你用這些通路修飾符沒有任何意義]。

作者:

Blackheart

出處:

http://linianhui.cnblogs.com

本文版權歸作者和部落格園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接配接,否則保留追究法律責任的權利。