1. 程式人生 > >C# 可空值類型

C# 可空值類型

static obj 引入 狀態 取出 struct opera 一個 boolean

我們知道,值類型的變量永遠不會為null,但在數據庫中的一個列可能允許值為空,但在CLR中沒有辦法將INT32值表示成null.

為了解決這個問題,CLR中引入了可空值類型,為了理解它是如何工作的,先來看看FCL中定義的system.Nullable<T>結構。

一、可空值類型的代碼

public struct Nullable<T> where T : struct
   { 
       //兩個字段表示狀態
       private Boolean hasValue = false; //假定null
       internal
T value = default(T);//假定所有位都為O public Nullable(T value) { this.value = value; this.hasValue = true; } public Boolean HasValue { get { return hasValue; } } public T Value { get { if (!hasValue) {
throw new InvalidOperationException("可空對象必須有值。"); } return value; } } public T GetValueOrDefault() { return value; } public T GetValueOrDefault(T defaultValue) { if (!hasValue) return
defaultValue; return value; } //重載equals方法 public override bool Equals(object obj) { if (!HasValue) return (obj == null); if (obj == null) return false; return value.Equals(obj); } //重載toString()方法 public override string ToString() { if (!HasValue) return ""; return value.ToString(); } public static implicit operator Nullable<T>(T value) { return new Nullable<T>(value); } public static explicit operator T(Nullable<T> value) { return value.Value; } }

可以看出,可空類型是一個結構類型,也就是說本身是一個值類型,實例仍然是在棧上,Nullable的類型參數被約束為struct,也就是說這個類型是為了值類型而設定的。

二、可空值類型的使用

我們要在代碼中使用一個可空的Int32,就可以像下面這樣寫:

Nullable<Int32> x = 5;
        Nullable<Int32> x = null;

但是在C#中一般是這樣寫

int? x = 5;
int? x = null;

三、合並操作符

C# 提供了一個空接合操作符,即??操作符,假如左邊的不為null,就返回這個操作數,如果左邊的為null,就返回右邊的操作數。

下面兩行代碼是等價的

int? b = null;
int a = (b.HasValue) ? b.Value : 123;
int a = b ?? 123;

四、可空類型的裝箱和拆箱

裝箱:當CLR對可空類型進行裝箱時,會檢查它是否為NULL,如果是,CLR不裝箱任何東西,直接返回NULL,如果可空實例不為NULL,CLR從可空實例中取出值並進行裝箱,也就是說,值為5的可空類型會裝箱成值為5的已裝箱INT32.

拆箱:如果已裝箱的值類型引用的是NULL,要把它拆箱成可空類型,那麽CLR會將可空類型的值設為NULL.

五、可空類型調用GetType

在可空類型上調用GetType,實際會撒謊說類型是T,而不是Nullable<T>。也就是說 Int32? x=5 ;在執行 x.GetType()時,會顯示System.Int32, 而不是System.Nullable<Int32>;

C# 可空值類型