1 引入可空类型
可空类型的声明方法是在基础类型之上加上一个问号"?"。
int ? i; i=10;
C#中,只有值类型才有可空类型(引用类型可以取null值),其中包括系统预定义的整数类型、字符类型、实数类型、布尔类型,以及各种结构类型和枚举类型。
2 泛型结构NullableType
2.1 概述
.NET是如何实现可空类型呢?一种设想是对每个值类型都定义一个新的可空类型,但这种做法工作量大,且没有扩展性:开发人员新定义的值类型就无法享受这一好处,除非他们每次都成对地定义值类型和可空类型。
.NET类库利用泛型的强大功能,一劳永逸地为所有值类型实现了可空类型。System中定义了一个泛型结构NullableType<T>,上一节采用的实际上是对可空类型的简写方式。int ? 等同于NullableType<int>。NullableType<T>的简写方式就是T?。
这种简写方式既可用于可空类型的声明,也可用于可空类型的构造。泛型结构NullableType<T>可实际定义的构造函数的原型为public Nullable<T>,所以可采用下面的代码来构造可空类型的实例:
int ? i = new int ?(5);//i=5; Nullable<int> j = new Nullable<int>(10);//j=10; Nullable<DateTime> dt = new DateTime?(DateTime.Now);//dt=Now
不过这种方式不适用于值为null的情况,因数NullableType<T>的构造函数的参数类型要求为T。下面的代码是不合法的:
int ? i=new int?(null);//error
可空类型是值类型和空值null的复合,但它在本质上还是一种值类型。可空类型的变量也是直接包含自身的数据,而不是指向目标数据的引用。因此可空类型本身也可以作为一种基础类型来构造新的可空类型。下面的代码都是合法的:
int? i = 10; int?? j = i; int??? k = j; Nullable<double> x = 3.14; Nullable<Nullbale<double>> y=x;
2.2 判断和取值
给定一个可空类型的变量,要知道它是不是空值null,可通过NullableType<T>的公用属性HasValue来确定。该属性为布尔值。
NullableType<T>的另一个公有属性Value的类型为T,它表示可空类型对应的基础类型的值。该属性仅在变量不为空值时有效,因此访问之前要检查属性HasValue的值是否为True。例如下面的代码会引发异常:
int? i = null; Console.WriteLine(i.Value);
正确的写法是:
if(i.HasValue) Console.WriteLine(i.Value);
HasValue和Value