c# 可空類型
可空類型是 System.Nullable 結構的實例。可空類型可以表示其基礎值類型正常範圍內的值,再加上一個 null 值。例如,Nullable<Int32>,讀作“可空的 Int32”,可以被賦值為 -2147483648 到 2147483647 之間的任意值,也可以被賦值為 null 值。Nullable<bool> 可以被賦值為 true 或 false,或 null。在處理數據庫和其他包含可能未賦值的元素的數據類型時,將 null 賦值給數值類型或布爾型的功能特別有用。例如,數據庫中的布爾型字段可以存儲值true 或 false,或者,該字段也可以未定義。
{
static void Main()
{
int? num = null;
if (num.HasValue == true)
{
System.Console.WriteLine("num = " + num.Value);
}
else
{
System.Console.WriteLine("num = Null");
}
//y is set to zero
int y = num.GetValueOrDefault();
// num.Value throws an InvalidOperationException if num.HasValue is false
try
{
y = num.Value;
}
catch (System.InvalidOperationException e)
{
System.Console.WriteLine(e.Message);
}
}
}
以上將顯示輸出:
num = Null
Nullable object must have a value.
可空類型概述
可空類型具有以下特性:
-
可空類型表示可被賦值為 null 值的值類型變量。無法創建基於引用類型的可空類型。(引用類型已支持 null值。)。
-
語法 T? 是 System.Nullable<T> 的簡寫,此處的 T 為值類型。這兩種形式可以互換。
-
為可空類型賦值與為一般值類型賦值的方法相同,如 int? x = 10; 或 double? d = 4.108;。
-
如果基礎類型的值為 null,請使用 System.Nullable.GetValueOrDefault 屬性返回該基礎類型所賦的值或默認值,例如 int j = x.GetValueOrDefault();
-
請使用 HasValue 和 Value 只讀屬性測試是否為空和檢索值,例如 if(x.HasValue) j = x.Value;
-
如果此變量包含值,則 HasValue 屬性返回 True;或者,如果此變量的值為空,則返回 False。
-
如果已賦值,則 Value 屬性返回該值,否則將引發 System.InvalidOperationException。
-
可空類型變量的默認值將 HasValue 設置為 false。未定義 Value。
-
-
使用 ?? 運算符分配默認值,當前值為空的可空類型被賦值給非空類型時將應用該默認值,如 int? x = null; int y = x ?? -1;。
-
不允許使用嵌套的可空類型。將不編譯下面一行:Nullable<Nullable<int>> n;
使用可空類型
可空類型可以表示基礎類型的所有值,另外還可以表示 null 值。可空類型可通過下面兩種方式中的一種聲明:
System.Nullable<T> variable
- 或 -
T? variable
T 是可空類型的基礎類型。T 可以是包括 struct 在內的任何值類型;但不能是引用類型。
有 關可能使用可空類型的示例,請考慮普通的布爾變量如何能夠具有兩個值:true 和 false。不存在表示“未定義”的值。在很多編程應用中(最突出的是數據庫交互),變量可存在於未定義的狀態。例如,數據庫中的某個字段可能包含值 true 或 false,但是它也可能根本不包含值。同樣,可以將引用類型設置為 null,以指示它們未初始化。
這種不一致會導致額外的編程工作,如使用附加變量來存儲狀態信息、使用特殊值,等等。可空類型修飾符使 C# 能夠創建表示未定義值的值類型變量。
可空類型示例
任何值類型都可用作可空類型的基礎。例如:
C#
int? i = 10;
double? d1 = 3.14;
bool? flag = null;
char? letter = ‘a‘;
int?[] arr = new int?[10];
可空類型的成員
可空類型的每個實例都具有兩個公共的只讀屬性:
HasValue
HasValue 屬於 bool 類型。當變量包含非空值時,它被設置為 true。
Value
Value 的類型與基礎類型相同。如果 HasValue 為 true,則說明 Value 包含有意義的值。如果 HasValue 為 false,則訪問 Value 將引發 InvalidOperationException。
在此示例中,HasValue 成員用於在嘗試顯示變量之前測試它是否包含值。
C#
int? x = 10;
if (x.HasValue)
{
System.Console.WriteLine(x.Value);
}
else
{
System.Console.WriteLine("Undefined");
}
也可以通過下面的方法測試是否包含值:
C#
int? y = 10;
if (y != null)
{
System.Console.WriteLine(y.Value);
}
else
{
System.Console.WriteLine("Undefined");
}
顯式轉換
可空類型可強制轉換為常規類型,方法是使用強制轉換來顯式轉換或者通過使用 Value 屬性來轉換。例如:
C#
int? n = null;
//int m1 = n; // Will not compile.
int m2 = (int)n; // Compiles, but will create an exception if x is null.
int m3 = n.Value; // Compiles, but will create an exception if x is null.
如果兩種數據類型之間定義了用戶定義的轉換,則同一轉換也可用於這些數據類型的可空版本。
隱式轉換
可使用 null 關鍵字將可空類型的變量設置為空,如下所示:
C#
int? n1 = null;
從普通類型到可空類型的轉換是隱式的。
C#
int? n2;
n2 = 10; // Implicit conversion.
運算符
可空類型還可以使用預定義的一元和二元運算符,以及現有的任何用戶定義的值類型運算符。如果操作數為空,這些運算符將產生一個空值;否則運算符將使用包含的值來計算結果。例如:
C#
int? a = 10;
int? b = null;
a++; // Increment by 1, now a is 11.
a = a * 10; // Multiply by 10, now a is 110.
a = a + b; // Add b, now a is null.
在執行可空類型的比較時,如果其中任一可空類型為 null,則比較結果將始終為 false。因此,一定不要以為由於一個比較結果為 false,相反的情況就會為 true。例如:
C#
int? num1 = 10;
int? num2 = null;
if (num1 >= num2)
{
System.Console.WriteLine("num1 is greater than or equal to num1");
}
else
{
// num1 is NOT less than num2
}
上面的 else 語句中的結論無效,因為 num2 為 null,所以不包含值。
??運算符
?? 運算符定義在將可空類型分配給非可空類型時返回的默認值。
C#
int? c = null;
// d = c, unless c is null, in which case d = -1.
int d = c ?? -1;
此運算符還可用於多個可空類型。例如:
C#
int? e = null;
int? f = null;
// g = e or f, unless e and f are both null, in which case g = -1.
int g = e ?? f ?? -1;
bool? 類型
bool? 可空類型可以包含三個不同的值:true、false 和 null。它們本身不能用於條件語句,如 if、for 或 while。例如,下面的代碼編譯失敗,並將報告編譯器錯誤 CS0266:
bool? b = null;
if (b) // Error CS0266.
{
}
這 是不允許的,因為 null 在條件上下文中意味著什麽並不清楚。為了能在條件語句中使用,可空布爾值可以顯式強制轉換為 bool,但是如果對象有值 null,將引發 InvalidOperationException。因此,在強制轉換為 bool 前檢查 HasValue 屬性很重要。
可空布爾值類似於 SQL 中使用的布爾變量類型。為了確保 & 和 | 運算符產生的結果與 SQL 的三值布爾類型一致,提供了以下預定義的運算符:
bool? operator &(bool? x, bool? y)
bool? operator |(bool? x, bool? y)
下表中列出了這些運算符的結果:
X | y | x&y | x|y |
---|---|---|---|
True |
true |
True |
true |
True |
false |
False |
true |
True |
null |
Null |
true |
False |
true |
False |
true |
False |
false |
False |
false |
False |
null |
False |
null |
Null |
true |
Null |
true |
Null |
false |
False |
null |
Null |
null |
Null |
null |
c# 可空類型