C#——可空值類型

轉載請註明出處:

http://hi.baidu.com/try__again/modify/blog/45bc5845c6db642bcffca39e

沒有值的時候怎麼辦?

對於一個引用類型的變量來說,其值是一個引用。而值類型變量的值是真正的值本身。對於引用類型來說,null是一個特殊的值,它表示“該引用變量沒有引用任何對象”。但是,它並不是一個有效的值類型的值。這非常容易理解,因爲如果C#設計者將null設計爲值類型的有效位,那麼勢必將增加內存開銷。

在C#1中,表示空值的值類型變量往往有如下幾種模式:

1、魔值,也就是說,犧牲一個值來表示空值。

2、引用類型包裝,它有兩種類型:直接利用object作爲變量類型,並根據需要進行裝箱和拆箱操作;對於一個可空值類型,爲其準備一個引用類型。

3、額外的bool標記

System,Nullable<T>:

該類型是可空類型的核心結構。它是一個泛型類型,且類型參數T存在一個值類型約束,T稱爲可空類型的基礎類型。它最重要的兩個屬性是HasValue和Value,前者是一個bool類型,它指出是否存在一個真正的值,後者則描述一個真正的值。

成員函數的調用:

using System;
using System.Collections.Generic;
using System.Text;

namespace CS_TEST
{
    class Program
    {
        static void Display(Nullable<int> x)
        {
            Console.WriteLine("HasValue:{0}", x.HasValue);
            if (x.HasValue)
            {
                Console.WriteLine("Value:{0}", x.Value);
                Console.WriteLine("Explicit conversion:{0}", (int)x);
            }
            Console.WriteLine("GetValueOrDefault():{0}", x.GetValueOrDefault());
            Console.WriteLine("GetValueOrDefault(10):{0}", x.GetValueOrDefault(10));
            Console.WriteLine("ToString():\"{0}\"", x.ToString());
            Console.WriteLine("GetHashCode();{0}", x.GetHashCode());
            Console.WriteLine();
        }
        static void Main(string[] args)
        {
            Nullable<int> x = 5;
            x = new Nullable<int>(5);
            Console.WriteLine("Instance with value:");
            Display(x);

            Nullable<int> y = new Nullable<int>();
            Console.WriteLine("Instance with value:");
            Display(y);

            Console.ReadLine();
        }
    }
}

Nullable:

這個類可以輔助泛型可空類型做一些事情,它只包含靜態方法,不能創建實例。

3個靜態方法:

public static int Compare<T>(Nullable<T> n1, Nullable<T> n2)public static bool Equals<T>(Nullable<T> n1, Nullable<T> n2)

第三個方法不是泛型方法:

public static Type GetUnderlyingType<Type nullbaleType>

如果第三個方法的參數是一個可空類型,那麼返回它的基礎類型,否則返回null。

C#2提供給可空類型的語法:

?修飾符:T? 等價於 Nullable<T>,用法完全一樣,只是語法不同,舉例如下:

            int? nullable = 5;//定義可空類型
            object boxed = nullable;//裝箱
            Console.WriteLine(nullable.GetType());

            int normal = (int)boxed;//拆箱成基礎類型
            Console.WriteLine(normal);

            nullable = (int?)boxed;//拆箱成可空類型
            Console.WriteLine(nullable);

            nullable = new int?();//將可空類型變量初始化爲空值
            boxed = nullable;//裝箱
            Console.WriteLine(boxed==null);

            nullable = (int?)boxed;//拆箱成可空類型
            Console.WriteLine(nullable.HasValue);

            //將空值可空類型拆箱成基礎類型,將拋出異常
            normal = (int)boxed;//拆箱成基礎類型
            Console.WriteLine(normal);

使用null進行賦值和比較:

C#允許使用null在比較和賦值中表示一個可空類型的空值,就跟引用類型一樣。

值得注意的一個地方:

DataTime? death;

DataTime birth;

求壽命的方法:

public TimeSpan Age

{

    get

    {

        if (death == null) return DataTime.Now - birth;

        return death.Value - birth;

    }

}

此外,null可以作爲參數進行傳遞,代表一個空值可空類型變量

思考:爲什麼在最後一行代碼中要使用death.Value - birth而非death - birth?

可空類型轉換:

null 到 T?的隱式轉換

T 到 T?的隱式轉換

T?到 T 的顯式轉換

S? 到 T?的轉換(顯式隱式皆可)

S 到 T?的轉換

S?到 T的顯示轉換

需要注意的是,如果S?是空值,那麼S?-->T的顯示類型轉換會拋出一個異常。

可空類型操作符的提升:略

提幾個比較值得注意的地方:

對於比較操作符,(null == null) == true,其它含有null的比較均爲false;

對於一元或者二元運算,如果有一個操作數爲null,那麼運算的結果也是一個null,即空值。

可空邏輯:

bool? a, b;

此時可空布爾類型有三種值,true, false, null。

此時布爾表達式的值取決於,如果空值的取值對布爾表達式的值有影響,那麼布爾表達式的值爲null。布爾表達式的值爲確定的布爾表達式的值。

空接合操作符:??

對於表達式:first??second

(1) 求first的值

(2) 如果first的值非空,那麼first的值就爲表達式的值

(3) 否則表達式的值爲second的值

因此,如前所述的代碼:

        if (death == null) return DataTime.Now - birth;

        return death.Value - birth;

可以寫成:

        return (death??DataTime.Now) - birth;

現在回答一下前面紅色標註的問題:

若使用death - birth,其結果是一個DataTime?,因爲從T到T?存在一個隱式類型轉換,而反過來的轉換澤必定是顯式的。直接使用death肯定是可以的,但是需要作者對返回的結果再進行處理。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章