为什么会有可空值类型:
当我们设计一个数据库时,可将一个数据库字段的数据类型定义成一个32位整数,并映射到FCL的Int32数据类型对象上。在数据库中的一个字段可能允许值为空,用.Net Framework处理数据库数据可能变得相当困难。因为在CLR中,没有办法将Int32值表示为null。为了解决这个问题,Microsoft在CLR中引入了可空值类型 (nullable value type)的概念。
19.1 C#对可空值类型的支持
可空类型也是值类型,只是它是包含null的一个值类型。
C#用问号表示法来声明并初始化变量。这个”?”修饰符只是C#提供的一个语法糖 (所谓语法糖,就是C#提供的一种方便的形式,肯定没有Int32? 这种类型。编译器认为Int32?就是System.Nullable< Int32>类型,即可空值类型)。
Nullable类型具有一个HasValue的
bool
类型只读属性,
当Nullable类型实例的该属性为
true
时,则表示该实例是非空实例,包含一个已知值Value。
HasValue为
false
时,访问Value属性将导致System.InvalidOperationException。
public struct Nullablewhere T : struct
C#允许在可空类型上执行转换和转型:
public static void ConversionsAndCasting() { //Nullablea = 5; Int32? a = 5; //从非可空的Int32转换为Nullable Int32? b = null; //从null隐式转换为Nullable Int32 c = (Int32)a; //从Nullable 显式转换为非可空Int32 //在可空基元类型之间转换 Double? d = 5;//Int32转型为Double Double? e = b;//Int32?转型为Double }
C#允许向可空类型的实例应用操作符:
public static void Operators(){ Int32? a = 5; Int32? b = null; a++; b = -b; a = a + 3; b = b * 3; if (a == null) { } else { } if (b == null) { } else { } if (a != b) { } else { } if (a < b) { } else { }}
19.2 C#的空接合操作符
为了实现Nullable数据类型转换成non-Nullable型数据
,C#提供了空接合操作符,即??操作符,它需要获取两个操作数。假如左边的操作数不为null,就返回左边的这个操作数的值。如果左边的操作数为null,就返回右边的操作数的值。
利用空接合操作符,可以方便地设置变量的默认值。避免在代码中写if / else语句,简化代码数量,从而有利于阅读。
public static void NullCoalescingOperator() { Int32? b = null; Int32 x = b ?? 123;//等价于x = (b.HasValue) ? b.Value : 123; }
19.3 CLR对可空值类型的特殊支持
其实可空值类型的装箱和拆箱操作大家可以理解为非可空值类型的装箱和拆箱的过程。只是CLR会提前检查下它是否为空,为null就不做任何处理。如果不为null,就按照非可空值类型的装箱和拆箱的过程来装箱和拆箱。