一、基础概念:
一般说来,null表示空类型,也就是表示什么都没有。在.NET中,null表示一个对象引用是无效的。作为引用类型变量的默认值,null是针对指针(引用)而言的,它是引用类型变量的专属概念,表示一个引用类型变量声明但未初始化的状态。在.NET中,对null有如下的基本规则和应用:
- null为引用类型变量的默认值,为引用类型的概念范畴。
- null不等同于0、“”、string.Empty,而表示一个空引用。
- 引用 is 或者 as 模式对类型进行判断或者转换时,需要做进一步的 null 检查。
- 判断一个变量是否为 null,可以应用==或者!=操作符来完成。
- 对任何值为 null 的变量操作,都会抛出 NullReferenceException 异常。
二、 Nullable<T>(可空类型)
一直以来,null 都是引用类型的特有产物,对值类型进行 null 操作将在编译器抛出异常提示,例如:
1: //抛出编译时错误
2: int i = null;
3: if (i==null)
4: {
5: Console.WriteLine("i is null.");
6: }
很多情况下,作为开发人员,我们更希望能以一种统一的方式来处理,同时也希望能够解决实际业务需求中对于“值”也可以为“空”这一实际情况的映射。因此,自.NET 2.0以来,这一特权被新的 System.Nullable<T>(即,可空值类型)的诞生打破,解除上述诟病可以很容易以下面的方式被实现:
1: //Nullable,解决了这一问题 2: int? i = null;3: if (i==null)4: {5: Console.WriteLine("i is null.");6: }
你可能很奇怪上述的例子中并没有任何Nullable的影子,实际上这是C#的一个语法糖,以下代码在本质上市完全等效的:
int? i = null;Nullable i = null;可空类型的伟大意义在于,通过Nullable<T>类型,.Net为值类型添加“可空性”,例如 Nullable<Boolean>的值就包括了 true、false 和 null,而 Nullable<Int32>则表示值既可以为整型也可以为 null。同时,可空类型实现了统一的方式来处理值类型和引用类型的“空”值问题,使得值类型也可以在运行时以 NullReferenceException 异常来处理。 另外,可控类型是内置于CLR的,因此它并非C#的独门绝技。
对于可空类型的小结:
- 可空类型表示值为 null 的值类型。
- 不允许使用嵌套的可空类型,例如 Nullable<Nullable<T>>。
- Nullalbe<T> 和 T? 是等效的。
- 对可空类型执行GetType方法,将返回类型 T,而不是 Nullable<T>。
- C#允许在可空类型上执行转换和转型,例如:
1: int? a = 100;2: Int32 b = (Int32)a;3: a = null;4:5: int? c = (int?)200;
三、??运算符
在实际的程序开发中,为了有效的避免发生异常情况,进行 null 判定是经常发生的事情。例如对于任意对象执行 ToString()操作,都应该进行必要的 null 检查,以避免发生不必要的异常提示,使用传统的三元运算符 (?:):
1: object obj = new object();2: string objName = obj == null ? string.Empty : obj.ToString();3: Console.WriteLine(objName);
.NET 2.0 中提供了新的操作运算符来简化 null 值的判定过程,这就是 ?? 运算符。以上过程可以使用以下代码来实现:
1: object obj = null;2: string objName = (obj ?? string.Empty).ToString();3: Console.WriteLine(objName);
?? 运算符,又称为 null-coalescing operator,如果左侧操作数为 null,则返回右侧操作数的值,如果不为 null 则返回左侧操作数的值。它既可以应用于可空类型,又可以应用于引用类型。应用 ??运算符实现了简洁的 null 判定,例如通过 ?? 运算符,可以实现一个有意思的代码技巧:
1: string a = null;2: string b = null;3: object c = 1;4: Console.WriteLine(a ?? null ?? b ?? null ?? c ?? null);
通过多次的 ?? 判定,可以很容易的从一堆候选者 a、b、c中挑选出不是null的那个。