1.什么是null
一般说来,null表示空类型,也就是表示什么都没有,但是“什么都没有”并不意味“什么都不是”。实际上,null是如此的重要,以致于在JavaScript中,Null类型就作为5种基本的原始类型之一,与Undefined、Boolean、Number和String并驾齐驱。这种重要性同样表现在.NET中,但是一定要澄清的是,null并不等同于0,"",string.Empty这些通常意义上的“零”值概念。相反,null具有实实在在的意义,这个意义就是用于标识变量引用的一种状态,这种状态表示没有引用任何对象实例,也就是表示“什么都没有”,既不是Object实例,也不是User实例,而是一个空引用而已。在.NET中,null表示一个对象引用是无效的。作为引用类型变量的默认值,null是针对指针(引用)而言的,它是引用类型变量的专属概念,表示一个引用类型变量声明但未初始化的状态,例如:
object obj = null;
2 Nullable<T>(可空类型)
一直以来,null都是引用类型的特有产物,对值类型进行null操作将在编译器抛出错误提示,例如:
//抛出编译时错误int i = null;
正如示例中所示,很多情况下作为开发人员,我们更希望能够以统一的方式来处理,同时也希望能够解决实际业务需求中对于“值”也可以为“空”这一实际情况的映射。因此,自.NET 2.0以来,这一特权被新的System.Nullable<T>(即,可空值类型)的诞生而打破,解除上述诟病可以很容易以下面的方式被实现:
//Nullable解决了这一问题int? i = null;
你可能很奇怪上述示例中并没有任何Nullable的影子,实际上这是C#的一个语法糖,以下代码在本质上是完全等效的:
int? i = null; Nullable i = null;
显然,我们更中意以第一种简洁而优雅的方式来实现我们的代码,但是在本质上Nullable<T>和T?他们是一路货色。可空类型的伟大意义在于,通过Nullable<T>类型,.NET为值类型添加“可空性”,例如Nullable<Boolean>的值就包括了true、false和null,而Nullable<Int32>则表示值即可以为整形也可以为null。
对于可空类型,使用注意:
- 可空类型表示值为null的值类型。
- 不允许使用嵌套的可空类型,例如Nullable<Nullable<T>> 。
- Nullable<T>和T?是等效的。
- 对可空类型执行GetType方法,将返回类型T,而不是Nullable<T>。
- c#允许在可空类型上执行转换和转型,例如:
int? a = 100; Int32 b = (Int32)a; a = null;
3 ??运算符
在实际的程序开发中,为了有效避免发生异常情况,进行null判定是经常发生的事情,例如对于任意对象执行ToString()操作,都应该进行必要的null检查,以免发生不必要的异常提示,我们常常是这样实现的:
string objName = obj == null ? string.Empty : obj.ToString();
因为上述实现是如此的频繁,所以.NET 3.0中提供了新的操作运算符来简化null值的判断过程,这就是:??运算符。上述过程可以以更加震撼的代码表现为:
string objName = (obj ?? string.Empty).ToString();
??运算符,又称为null-coalescing operator,如果左侧操作数为null,则返回右侧操作数的值, 如果不为null则返回左侧操作数的值。它既可以应用于可空类型,又可以应用于引用类型。