C#中的两个问号:这是什么以及如何使用

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

C#中的两个问号:不是错误,而是强大的工具

\n\n

想象一下:你在编写C#代码,突然看到??结构。第一反应是拼写错误?多了一个符号?实际上,这是该语言中最优雅、最实用的运算符之一——null合并(null-coalescing operator)。如果你曾经遇到过NullReferenceException并诅咒一切——这个运算符将成为你的救生圈。

\n\n

在本文中,我们将详细解释C#中两个问号的含义,如何正确使用它们,它们与三元运算符的区别,并展示实际案例。开始吧!

\n\n

C#中的??运算符是什么?

\n\n

??运算符(两个问号)是一个二元运算符,如果左操作数不为null,则返回左操作数;否则返回右操作数。简单来说:“如果左边不是null,取左边;否则取右边”。

\n\n

语法非常简单:

\n\n
var result = left ?? right;
\n\n

其中:

\n
    \n
  • left — 可能为null的值;
  • \n
  • right — 默认值(如果右侧类型为可空类型,则不能为null)。
  • \n
\n\n

第一个示例:避免null

\n\n

假设你有一个变量string? name(可空字符串)。你想显示用户名,如果没有则显示“访客”:

\n\n
string? name = GetUserName(); // 可能返回null\nstring displayName = name ?? "访客";\nConsole.WriteLine(displayName);
\n\n

如果没有??运算符,你需要这样写:

\n\n
string displayName = (name != null) ? name : "访客";
\n\n

你同意吗?第一种写法读起来像普通句子:“名字或访客”。很优雅,对吧?

\n\n

??=运算符:新一代null合并

\n\n

从C# 8.0开始,引入了??=运算符——这是带有null合并的赋值简写形式。它仅在左操作数等于null时,将右操作数的值赋给左操作数。

\n\n

语法:

\n\n
left ??= right;
\n\n

这等价于:

\n\n
if (left == null) left = right;
\n\n

??=示例

\n\n
List<int>? numbers = null;\nnumbers ??= new List<int>(); // numbers现在 = new List<int>()\nnumbers.Add(42);\nConsole.WriteLine(numbers.Count); // 1
\n\n

注意:如果numbers已经初始化(不为null),则不会发生赋值。这非常适合惰性初始化。

\n\n

与三元运算符(? :)的比较

\n\n

许多初学者混淆??和三元运算符? :。让我们一次性搞清楚:

\n\n
    \n
  • 三元运算符是if-else的简写形式。它检查任何布尔条件:条件 ? 值为true时的结果 : 值为false时的结果。
  • \n
  • ??运算符仅检查是否为null。这是一个专门针对特定任务的特殊情况。
  • \n
\n\n

三元运算符示例:

\n\n
int age = 18;\nstring status = (age >= 18) ? "成年人" : "未成年人";
\n\n

如果尝试用三元运算符替换??:

\n\n
string? name = null;\nstring displayName = name != null ? name : "访客"; // 可以工作,但更长\nstring displayName2 = name ?? "访客"; // 更短且更清晰
\n\n

结论:当需要简单地将null替换为默认值时,使用??。对于所有其他条件,使用三元运算符。

\n\n

??运算符链

\n\n

你可以将多个??运算符链接在一起。当有多个可能的值来源时,这很方便:

\n\n
string? firstChoice = GetFromCache                

博客

书籍推荐