运算符简介
C# 很大程度上的传承了 C 语言的运算符,因此在大部分情况下两者的用法是相似的,一些比较细微的使用规则需要在实际应用的过程中发现。
比较直观能够看到的就是 C# 中增加了一些特殊的运算符,比如:可空运算符(?.)
、空合并运算符(??)
和引用类型的运算符(is、as)
等。
1、可空类型
C# 提供了一个特殊的数据类型,nullable 类型(可空类型)——该类型可以表示其基础值类型正常范围内的值,再加上一个 null 值。例如:
Nullable< Int32 >
,读作“可空的 Int32”,可以被赋值为 -2,147,483,648 到 2,147,483,647 之间的任意值,也可以被赋值为 null 值。- 类似的,
Nullable< bool >
变量可以被赋值为 true 或 false 或 null。
在处理数据库和其他包含可能未赋值的元素的数据类型时,将 null 赋值给数值类型或布尔型的功能特别有用。例如,数据库中的布尔型字段可以存储值 true 或 false,或者,该字段也可以未定义。
声明一个 nullable 类型(可空类型)的语法如下:
< data_type> ? <variable_name> = null;
简单来说,就是在数据类型和变量名之间添加一个单问号“?”,申明这个变量是一个可空数据类型。下面的实例演示了可空数据类型的用法:
using System; // 引入 System 命名空间
namespace CalculatorApplication // 命名空间定义
{
class NullablesAtShow // 定义类 NullablesAtShow
{
static void Main(string[] args) // 主函数
{
int? num1 = null; // 定义一个可空类型的 int,值为 null
int? num2 = 45; // 定义一个可空类型的 int,值为 45
double? num3 = new double?(); // 定义一个可空类型的 double,值为 null
double? num4 = 3.14157; // 定义一个可空类型的 double,值为 3.14157
bool? boolval = new bool?(); // 定义一个可空类型的 bool,值为 null
// 显示值
Console.WriteLine("显示可空类型的值: {0}, {1}, {2}, {3}",
num1, num2, num3, num4);
Console.WriteLine("一个可空的布尔值: {0}", boolval);
Console.ReadLine(); // 读取用户输入,等待用户按下 Enter 键
}
}
}
在上面的代码中我们定义了四个可空类型的变量:num1, num2, num3, num4,其中 num1 和 num3 的值为 null,num2 和 num4 分别为 45 和 3.14157。另外还定义了一个可空类型的布尔变量 boolval,值也为 null。最后,使用 Console.WriteLine 方法分别输出这些变量的值。
当上面的代码被编译和执行时,它会产生下列结果:
显示可空类型的值: , 45, , 3.14157
一个可空的布尔值:
需要注意两点:
-
这里的
double?
可以被写成Nullable<double>
的形式,它是一个 C# 内置的结构体,可用于在值类型(如 int、double 等)上创建可空类型,所以上面的代码可以写成Nullable<double> num3 = new Nullable<double>();
。 -
new double?()
表示创建一个新的可空 double 类型实例,并将其初始化为 null。如果我们在代码中直接写double? num3 = null;
,则会将 num3 初始化为 null,效果是一样的。
2、可空运算符
C# 中的可空运算符 “?.”(又称为“空值传播运算符”)是一种特殊的运算符,用于在访问可能为 null 的对象的成员时避免出现 NullReferenceException
异常。
在 C# 中,如果对一个 null 对象的成员进行访问,就会出现 NullReferenceException
异常。使用 ?. 运算符
可以在成员操作前先判断对象是否为 null,如果为 null 则不进行操作,直接返回 null。例如:
MyClass obj = null;
string result = obj?.ToString(); // 返回 null,不会抛出异常
上面的代码中,obj 为 null,调用 ToString()
方法会出现 NullReferenceException
异常。但是使用 ?. 运算符
就可以避免这种异常,直接返回 null。
实际上我们在可空类型中提到的单问号也是可空运算符的一种,也就是说,可空运算符在 C# 中有两种写法:
- 问号加点(?.):表示如果对象不为 null,则调用对象的属性或方法;如果对象为 null,则返回 null,不会出现空引用异常。例如:
string s = null; int? length = s?.Length;
上面的代码中,如果 s 不为null,则返回 s 的长度,否则返回 null。
- 问号(?):可以将值类型转换为可空类型。例如:
int i = 123; int? j = i;
上面的代码中,将 i 赋值给 j,j 就变成了一个可空类型的整数,其值为 123。
3、空值合并运算符
除了上面提到的可空运算符外,还有一个类似的运算符 ??
,叫做“null 合并运算符”。Null 合并运算符为可空类型和引用类型定义了一个预设值,以防它的值为 Null。
using System;
namespace CalculatorApplication
{
class NullablesAtShow
{
static void Main(string[] args)
{
double? num1 = null;
double? num2 = 3.14157;
double num3;
num3 = num1 ?? 5.34; // num1 如果为空值则返回 5.34
Console.WriteLine("num3 的值: {0}", num3);
num3 = num2 ?? 5.34;
Console.WriteLine("num3 的值: {0}", num3);
Console.ReadLine();
}
}
}
上面的代码中,num1 为 null,使用 ?? 运算符
可以返回一个预设值 -5.34;num2 不为 null,使用 ?? 运算符
返回它的值 3.14157。输出结果如下:
num3 的值: 5.34
num3 的值: 3.14157
- 需要注意的是,在使用 ?? 运算符时,左侧的变量必须是可空类型/引用类型,否则将会出现编译错误。
- 其实
?? 运算符
可以理解为三元运算符?:条件运算符
的简化形式,以下两行代码效果相同:
num3 = num1 ?? 5.34;
num3 = (num1 == null) ? 5.34 : num1;