可空值类型[Nullable value type]
小结:
可空值类型[Nullable value type]
1. 一个值类型的变量永远不可能为null,它总是包含值类型的值本身。但某些情况下,这会带来问题。例如,设计一个数据库时,可以将一个列的数据类型定义成一个32位整数,并映射到FCL的Int32数据类型。但是,数据库中的一个列是允许值为空的,使用.Net Framework来处理数据库数据可能变得相当困难,因为CLR中没有办法将一个Int32值表示成null。
为了解决这个问题,Microsoft在CLR中添加了可空值类型(nullable value type)【System.Nullable< T >】的概念。
CLR中的定义:public struct Nullable<T> where T : struct{...}
2. C#对可空值类型的支持
C#中采用问号表示法来声明并初始化可空值类型变量:
Int32? x = 5;
Int32? y = null;
3. C#的空合并操作符[??]
获取两个操作数,假如左边的操作数不为null,就返回这个操作数的值;如果左边的操作数为null,就返回右边的操作数的值。利用空合并操作符,可以方便地设置变量的默认值。
空合并操作符的一个好处在于:它既能用于引用类型,也能用于可空值类型。如:
Int32? b = null;
Int32 x = b ?? 123; //等价于: Int32 x = (b.HasValue) ? b.Value : 123;
String temp = GetFilename();
String filename = GetFilename() ?? "Untitled";//等价于: filename = (temp != null) ? temp : "Untitled";
4. 对可空值类型进行装箱
当CLR对一个Nullable<T>实例进行装箱时,它会检查它是否为null。如果是,CLR不会对它进行任何装箱操作,直接返回null值。如果可空实例不为null,CLR就从可空实例中取出值,并对其进行装箱。也就是说,一个值为5的Nullable<Int32>会装箱成值为5的Int32类型。
Int32? x = 5;
Int32? y = null;
Object o = y;//不会进行装箱操作,返回null值
Console.WriteLine("o is null = {0}", o == null);//"true"
Object o = x;//o引用一个已装箱的Int32
Console.WriteLine("o's type is {0}", o.GetType());//"System.Int32"
5. 对可空值类型进行拆箱
Object o = 5;//o引用一个已装箱的Int32
Int32 a = (Int32)o;//拆箱成一个Int32
Int32? b = (Int32?)o;//拆箱成一个Nullable<Int32>
6. 通过可空值类型来调用GetType
在一个Nullable<T>对象上调用GetType时,CLR实际返回的是T类型,而不是Nullable<T>,如:
Int32? x = 5;
Console.WriteLine(x.GetType());//显示"System.Int32",而非Nullable<Int32>