C# 中 ?、?.、??、??= 运算符的用法详解

唐可
唐可
发布时间:2026-10-15 | 5人浏览过
原创

在 C# 开发中,正确处理 null 值是避免运行时错误的关键。本文详细解析了四个核心运算符:? 声明可空类型,?? 获取默认值,?. 安全访问成员,以及 ?=? 条件赋值,助您写出更健壮的代码。

1. 可空类型修饰符 ?

在 C# 中,引用类型(如 string)默认可以为 null,但值类型(如 int、DateTime)默认不能。若试图将 null 赋给不可空的值类型,编译器会报错。为了使值类型也能表示“无值”状态,C# 提供了可空类型机制,使用后缀 ? 表示,其通用形式为 T?,本质上是 Nullable<T> 的语法糖。

以下代码展示了如何声明和使用可空值类型:

// 引用类型本身支持 null
string str = null;

// 以下语句编译报错,因为 int 是值类型,默认可为空
// int i = null;

// 使用 '?' 使值类型变为可空类型
int? i = null;       // 表示可空的整数
DateTime? time = null; // 表示可空的时间

2. 空合并运算符 ??

空合并运算符 ?? 用于确定对象是否为 null。如果左侧操作数不为 null,则返回该操作数的值;如果左侧为 null,则计算并返回右侧操作数的值。它常用于为变量提供默认值。

// 当 a 不为空时返回 a,为 null 时返回 b
var c = a ?? b;

3. 空传播运算符 ?.(条件访问)

当需要对可能为 null 的对象进行属性或方法访问时,直接使用点号(.)可能会抛出 NullReferenceException。空传播运算符 ?.(也称为条件访问运算符)可以安全地执行此操作:如果对象为 null,则表达式立即返回 null,后续链式调用不再执行。

假设有一个 Person 对象,以下两段代码逻辑等效。第一段使用了 ?. 进行简化:

// 仅当 Person 非 null 时,才访问其 Name 属性
// 注意:原草稿示例逻辑有误,修正为标准用法:
// 假设我们要获取 Person.Name 的值,若 Person 为 null 则返回 null
string name = Person?.Name;

其展开后的等价代码如下(通常配合三元运算符使用):

string name = Person == null ? null : Person.Name;

提示:在使用 ?. 时,确保整个表达式的结果类型与目标属性的可空性匹配。例如,访问值类型的 nullable 属性时需小心装箱问题。

4. 空合并赋值运算符 ??=

从 C# 8.0 开始,引入了空合并赋值运算符 ?=?。这是一个组合操作符,仅当左侧操作数的求值结果为 null 时,才会将右侧操作数的值赋值给左侧操作数。如果左侧不为 null,右侧操作数甚至不会被评估。这在初始化集合或配置对象时非常有用。

List<int> numbers = null;
int? i = null;

// 由于 numbers 为 null,执行赋值初始化
numbers ??= new List<int>();

// i 为 null,赋予默认值 17
numbers.Add(i ??= 17);

// i 当前为 17(非 null),故不执行赋值,再次添加 17
numbers.Add(i ??= 20);

Console.WriteLine(string.Join(" ", numbers)); // 输出:17 17
Console.WriteLine(i);                        // 输出:17
相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表