利用Nullable<T>所擁有的屬性來判斷是否為null

這篇文章基本上是屬於廢文等級,純粹是用來協助自己記憶用的。一般來說,在宣告實質型別(Value Type)可為null時,在取值時我都會採用Nullable<T>==null的形式來進行判斷,但事實上,是可以使用Nullable<T>所提供的屬性來進行判斷的,這樣一來程式碼的可讀性又往上提升了一點點了。

在這邊小提醒一下,Nullable<T>是以Struct(結構)的型態出現的喔!

HasValue屬性

取得值,指出目前的Nullable<T>物件是否具有其基礎類型的有效值。

Value屬性

取得目前Nullable<T>物件的值,如果這個物件已有指派的有效基礎值。

程式碼示範以及註解說明

static void Main(string[] args)
{
	//兩種寫法都可以
	int? Test1 = 1234;
	Nullable<int> Test2 = 5678;

	//大家都是System.Int32
	WriteLine($"{Test1.GetType()} / {Test2.GetType()}");

	if (Test1 != null)	//以後盡量不要再用這種寫法了
	{ WriteLine(Test1.Value); }

	if (Test2.HasValue)	//改用這種寫法清爽多了
	{ WriteLine(Test2.Value); }

	Read();
}

特別注意!若沒有經過Nullable<T>==null或者是Nullable<T>.HasValue的檢查,就直接用Nullable<T>.Value去調用到一個可能為null的實質型別,當null真的發生時,會吐出錯誤「System.InvalidOperationException」,所以取值時請小心。

最後來看一下Nullable<T>原始碼

本草綱目Microsoft .NET Reference Source有紀載,看原始碼輕鬆又便利,真是太棒啦!

[Serializable]
[System.Runtime.Versioning.NonVersionable] // This only applies to field layout
public struct Nullable<T> where T : struct
{
	private bool hasValue; 
	internal T value;

	[System.Runtime.Versioning.NonVersionable]
	public Nullable(T value) {
		this.value = value;
		this.hasValue = true;
	}        

	public bool HasValue {
		[System.Runtime.Versioning.NonVersionable]
		get {
				return hasValue;
		}
	} 

	public T Value {
		get {
			if (!hasValue) {
				ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_NoValue);
			}
			return value;
		}
	}
 
 ... BraBra ...
  1. 看到[Serializable]屬性了,代表可以序列化。
  2. Nullable<T>是struct結構。
  3. 利用public Nullable(T value)來進行建構,若有實值進來,則馬上把value與hasValue欄位灌值進去。
  4. 因為struct沒有辦法對欄位進行初始化賦值,所以巧妙的利用private bool hasValue;布林值實值天生的預設值false來進行預設。所以當從來沒有使用過(建構子沒有被調用過),hasValue自然就是false了。
  5. Value屬性被調用前,struct內部還是會先去檢查一下hasValue欄位是否為true,否則就吐出InvalidOperationException錯誤。

以上就是有關於Nullable<T>的一篇廢文,謝謝大家。

Nullable<T> HasValue Value GetType() InvalidOperationException