动态

详情 返回 返回

可為 null 的值類型 - 动态 详情

可為 null 值類型 T? 表示其基礎值類型 T 的所有值及額外的 null 值。例如,可以將以下三個值中的任意一個指定給 bool? 變量:true、false 或 null。基礎值類型 T 本身不能是可為 null 的值類型。

任何可為 null 的值類型都是泛型 System . Nullable < T > 結構的實例。可使用以下任何一種可互換形式引用具有基礎類型 T 的可為 null 值類型:Nullable < T > 或 T?。

需要表示基礎值類型的未定義值時,通常使用可為空的值類型。例如,布爾值或 bool 變量只能為 true 或 false。但是,在某些應用程序中,變量值可能未定義或缺失。例如,某個數據庫字段可能包含 true 或 false,或者它可能不包含任何值,即 NULL。在這種情況下,可以使用 bool? 類型。

聲明和賦值

由於值類型可隱式轉換為相應的可為 null 的值類型,因此可以像向其基礎值類型賦值一樣,向可為空值類型的變量賦值。還可分配 null 值。例如:

double? pai = 3.14;
char? zm = 'a';

int m2 = 10;
int? m = m2;

bool? flag = null;

// 一個可 null 值類型的數組:
int? [ ] arr = new int? [ 10 ];

可為空值類型的默認值表示 null,也就是説,它是其 Nullable < T > . HasValue 屬性返回 false 的實例。

檢查可為空值類型的實例

您可以使用 is 操作符和類型模式來檢查可 null 值類型的實例是否為 null,並獲取基礎類型的值:

int? a = 42;
if ( a is int A值 )
    {
        Console . WriteLine ( $"a 是 {A值}" );
    }
else
    {
        Console . WriteLine ( "a 沒有值" );
    }
// a 是 42

始終可以使用以下只讀屬性來檢查和獲取可為空值類型變量的值:

  • Nullable < T > . HasValue 指示可為空值類型的實例是否有基礎類型的值。
  • 如果 HasValue 為 true,則 Nullable < T > . Value 獲取基礎類型的值。如果 HasValue 為 false,則 Value 屬性將引發 InvalidOperationException。

以下示例中的使用 HasValue 屬性在顯示值之前測試變量是否包含該值:

int? a = 42;
if ( a . HasValue )
    {
        Console . WriteLine ( $"a 是 {a . Value}" );
    }
else
    {
        Console . WriteLine ( "a 沒有值" );
    }
// a 是 42

還可將可為 null 的值類型的變量與 null 進行比較,而不是使用 HasValue 屬性,如以下示例所示:

int? a = 42;
if ( a != null )
    {
        Console . WriteLine ( $"a 是 {a . Value}" );
    }
else
    {
        Console . WriteLine ( "a 沒有值" );
    }
// a 是 42

從可為 null 的值類型轉換為基礎類型

如果要將可為空值類型的值分配給不可以為 null 的值類型變量,則可能需要指定要分配的替代 null 的值。使用 Null 合併操作符 ?? 執行此操作(也可將 Nullable < T > . GetValueOrDefault ( T ) 方法用於相同的目的):

int? a = 28;
int b = a ?? -1;
Console . WriteLine ( $"b 是 {b}" ); // b 是 28

int? c = null;
int d = c ?? -1;
Console . WriteLine ( $"d 是 {d}"); // d 是 -1

如果要使用基礎值類型的默認值來替代 null,請使用 Nullable < T > . GetValueOrDefault ( ) 方法。

還可以將可為空的值類型顯式強制轉換為不可為 null 的類型,如以下示例所示:

int? n = null;

// int m1 = n; // 無法編譯
int n2 = (int)n; // 編譯通過,但產生 exception 因為 n 是 null

在運行時,如果可為空的值類型的值為 null,則顯式強制轉換將拋出 InvalidOperationException。

不可為 null 的值類型 T 隱式轉換為相應的可為空值類型 T?。

提升的運算符

預定義的一元運算符和二元運算符或值類型 T 支持的任何重載運算符也受相應的可為空值類型 T? 支持。如果一個或全部兩個操作數為 null,則這些運算符(也稱為提升的運算符)將生成 null;否則,運算符使用其操作數所包含的值來計算結果。例如:

int? a = 10;
int? b = null;
int? c = 10;

a++;     // a 是 11
a *= c;  // a 是 110
a += b;  // a 是 null

備註:對於 bool? 類型,預定義的 & 和 | 運算符不遵循此部分中描述的規則:即使其中一個操作數為 null,運算符計算結果也可以不為 NULL。

對於比較運算符 <、>、<= 和 >=,如果一個或全部兩個操作數都為 null,則結果為 false;否則,將比較操作數的包含值。請勿作出如下假定:由於某個特定的比較(例如 <=)返回 false,則相反的比較 (>)返回 true。以下示例顯示 10 既不大於等於 null,也不小於 null。

int? a = 10;
Console . WriteLine ( $"{a} ≥ null:{a >= null}" );
Console . WriteLine ( $"{a} < null:{a < null}" );
Console . WriteLine ( $"{a} == null:{a == null}");
// 10 ≥ null:False
// 10 < null:False
// 10 == null:False

int? b = null;
int? c = null;
Console . WriteLine ( $"null ≥ null:{b >= c}" );
Console . WriteLine ( $"null == null:{b == c}" );
// null ≥ null:False
// null == null:True

對於相等運算符 ==,如果兩個操作數都為 null,則結果為 true;如果只有一個操作數為 null,則結果為 false;否則,將比較操作數的包含值。

對於不等運算符 !=,如果兩個操作數都為 null,則結果為 false;如果只有一個操作數為 null,則結果為 true;否則,將比較操作數的包含值。

如果在兩個值類型之間存在用户定義的轉換,則還可在相應的可為空值類型之間使用同一轉換。

boxed 和 unboxed

可為空值類型的實例 T? 已 boxed,如下所示:

  • 如果 HasValue 返回 false,則生成 null 引用。
  • 如果 HasValue 返回 true,則基礎值類型 T 的對應值將 boxed,而不對 Nullable < T > 的實例進行 boxed。

可將值類型 T 的已 boxed 值 unboxed 到相應的可為 null 值類型 T?,如以下示例所示:

int a = 41;
object aBoxed = a;
int? aNullable = ( int? )aBoxed;
Console . WriteLine ( $"可為 null 的值 a:{aNullable}" );

object aNullableBoxed = aNullable;
if ( aNullableBoxed is int A值 )
    {
        Console . WriteLine ( $"A裝箱值:{A值}" );
    }
// 可為 null 的值 a:41
// A裝箱值:41

如何確定可為 null 的值類型

下面的示例演示瞭如何確定 System . Type 實例是否表示已構造的可為空值類型,即具有指定類型參數 T 的 System . Nullable < T > 類型:

Console . WriteLine ( $"int? 是 {( IsNullable ( typeof ( int? ) ) ? "nullable" : "non nullable" )} 值類型" );
Console . WriteLine ( $"int is {( IsNullable ( typeof ( int ) ) ? "nullable" : "non-nullable")} 值類型");

// int? 是 nullable 值類型
// int 是 non-nullable 值類型

如示例所示,使用 typeof 運算符來創建 System.Type 實例。

如果要確定實例是否是可為 null 的值類型,請不要使用 Object . GetType 方法獲取要通過前面的代碼測試的 Type 實例。如果對值類型可為 null 的實例調用 Object . GetType 方法,該實例將 boxed 到 Object。由於對可為 null 的值類型的非 NULL 實例的 boxed 等同於對基礎類型的值的 boxed,因此 GetType 會返回表示可為 null 的值類型的基礎類型的 Type 實例:

int? a = 17;
Type lxOfA = a . GetType ( );
Console . WriteLine ( lxOfA . FullName );
// System . Int32

另外,請勿使用 is 運算符來確定實例是否是可為 null 的值類型。如以下示例所示,無法使用 is 運算符區分可為 null 值類型實例的類型與其基礎類型實例:

int? a = 14;
if ( a is int )
    {
        Console . WriteLine ( "int? 類型的實例與 int 類型兼容" );
    }

int b = 17;
if ( b is int? )
    {
        Console . WriteLine ( "int 類型的實例與 int? 類型兼容" );
    }
// int? 類型的實例與 int 類型兼容
// int 類型的實例與 int? 類型兼容

請改為使用第一個示例中的 Nullable . GetUnderlyingType 和 typeof 運算符,以檢查實例是否具有可為 null 的值類型。

備註:此部分中所述的方法不適用於可為 null 的引用類型的情況。

Add a new 评论

Some HTML is okay.