JAVA和C/C++语言,大多数基本类型,例如int,double这样的值类型必须包含一个值,但是不能为空值(null),只有引用类型(String和Object对象)可以为空值(null)。但是和JAVA和C/C++语言不同的是,C#可以允许值类型为空,这样做还是很有用的,尤其是在处理数据库操作或者解析JSON/XML文件时
- ?运算符
此操作符解读为可空操作符
泛型使用System.Nullable<T>类型提供了使值类型可以为空的一种方式。例如:
System.Nullable<int> nullableInt;
这行代码声明了一个变量nullableInt,它可以拥有int变量能包含的任意值,还可以拥有null值,所以下面的代码是合法的:
nullableInt = null;
为了书写方便,用int? 代替System.Nullable<int>
int? testNum = 4;
int? result = testNum * 2;
如果写成以下的形式,代码是不会被编译的
int? testNum = 4;
int result = testNum * 2;
可以通过显示的转化或者Value的属性访问上述的代码
int? testNum = 4;
int result = (int)testNum * 2; //显示的强制转化
int result = testNum.Value * 2; //Value属性,只要testNum不为空,就可以正常运行,若testNum为null,则会生成System.Invalid-OperationException类型的异常
- ??运算符
此操作符解读为空合并操作符,此操作符为右结合运算符
这是一个二目运算符,允许给可能等于null表达提供另一个值,相当于C/C++/JAVA里的二目运算符?:,而C#为其提供了简化的形式。
假设有2个操作数,a和b,如果a为空就使用b的值,如果a不为空则用a本身
如果按C/C++/JAVA的语法规则,则应该表示为
a == null ? b : a
C#则简化为
a??b
实际上二目运算符?:,在C#中同样可以使用,??只是为其提供了另一种简化形式,一般使用??二目运算符都会有赋值语句,例如上面的例子,可以写成
result = a??b; //表示如果a为空则result=b,否则result=a
- ?.运算符
此操作符解读为空条件操作符
假设我们要去超市买可乐,假设超市是个静态类,可乐是一个方法,如果没有可乐就返回null
int count = 0;
if ( null != SuperMarket.GetCola()){
count = SuperMarket.GetCola();
}
以上的代码是没有问题的,很多时候我们图省事又或者欠考虑,经常写成下面的代码:
int count = SuperMarket.GetCola();
但是这个已经没有可乐了,返回的是空值null,上面的代码就会抛出System.ArgumentNullException的异常
这个时候如果使用?.运算符,就会把返回值设置为null,而不是抛出一个异常
int? count = SuperMarket?.GetCola();