在日常 C# 编程中,我们经常需要判断对象是否为空(null),
否则直接访问成员可能会抛出 NullReferenceException。
为了解决这种繁琐的空判断,C# 提供了两个非常实用的语法糖:
?.------ 空条件运算符(null-conditional operator)??------ 空合并运算符(null-coalescing operator)
✳️ 一、空条件运算符(?.)
✅ 语法:
csharp
A?.B
💬 含义:
如果 A 不为 null,返回 A.B;
如果 A 为 null,整个表达式直接返回 null。
🧩 等价写法:
csharp
var result = (A != null) ? A.B : null;
💡 示例:
csharp
Person p = null;
// 不会抛异常,直接返回 null
var name = p?.Name;
// 等价于:
string name = (p != null) ? p.Name : null;
这样写的好处是:安全访问,不会触发空引用异常。
✳️ 二、空合并运算符(??)
✅ 语法:
csharp
A ?? B
💬 含义:
- 如果左侧
A不为null,返回A; - 如果左侧
A为null,返回右侧B。
🧩 等价写法:
csharp
var result = (A != null) ? A : B;
💡 示例:
csharp
string name = userName ?? "匿名用户";
如果 userName 为 null,则结果为 "匿名用户"。
⚙️ 三、组合使用:?. 与 ??
这两个运算符常常配合使用,用于安全访问链式对象,并提供默认值。
🌰 示例:
csharp
var name = player?.Info?.Name ?? "未知玩家";
解释:
-
player?.Info?.Name- 如果
player或Info为null,整个表达式结果为null
- 如果
-
?? "未知玩家"- 如果左侧是
null,则使用"未知玩家"
- 如果左侧是
最终效果:
👉 安全地获取玩家名称,如果取不到,就返回一个默认字符串。
⚡ 四、总结对比
| 运算符 | 名称 | 用法 | 含义 | 等价逻辑 |
|---|---|---|---|---|
?. |
空条件运算符 | A?.B |
如果 A 不为空则访问 A.B,否则返回 null |
(A != null) ? A.B : null |
?? |
空合并运算符 | A ?? B |
如果 A 为空则返回 B,否则返回 A |
(A != null) ? A : B |
🎯 五、实际使用建议
- 使用
?.:当你不确定对象是否为null,但仍要访问其成员。 - 使用
??:当你想在值为空时提供一个默认值。 - 组合使用 :
player?.Info?.Name ?? "未知"是最常见的写法。
✅ 小结
| 表达式 | 说明 | 结果 |
|---|---|---|
A?.B |
如果 A 不为空返回 A.B,否则 null |
A == null ? null : A.B |
A ?? B |
如果 A 不为空返回 A,否则 B |
A == null ? B : A |
A?.B ?? C |
如果 A 为空或 A.B 为空,返回 C |
安全且简洁的写法 |
✍️ 示例总结:
csharp
var playerName = player?.Info?.Name ?? "暂无玩家";
👉 安全访问对象属性链,并提供默认值。
避免 NullReferenceException,代码更优雅。