C# 如何使用?、? 和 ??的区别和使用案例

目录

? 运算符

使用案例

?? 运算符

使用案例

总结


在 C# 中,? 和 ?? 运算符在处理 null 值时起着不同的作用,并且具有特定的使用场景。

? 运算符

? 运算符,也称为空条件运算符,在 C# 6.0 及更高版本中引入。它允许你在不进行显式类型转换的情况下检查引用类型的变量是否为 null。如果变量为 null,则整个表达式的结果也是 null,并且不会执行 ? 之后的代码块。这有助于避免空引用异常。

使用案例

假设我们有一个方法,该方法返回一个字符串,或者在某些情况下返回 null

string GetNullableString();

如果我们想在返回的字符串上调用一个方法(例如 .Length),直接调用可能会引发异常,因为如果返回的是 null,尝试获取其长度会导致空引用异常。使用 ? 运算符可以安全地解决这个问题:

string result = GetNullableString()?.Length;

如果 GetNullableString() 返回 null,则整个表达式的结果也是 null,不会尝试访问 Length 属性。

?? 运算符

?? 运算符是一个逻辑运算符,也称为空合并运算符。当左侧的操作数为 null 时,它返回右侧的操作数作为结果。如果左侧的操作数不为 null,则返回左侧的操作数。它通常用于为可能为 null 的变量提供一个默认值。

使用案例

假设我们有一个字符串变量,可能没有初始化:


  
string someString;

如果直接访问这个变量的长度,因为它是 null,会抛出空引用异常。我们可以使用 ?? 运算符来提供一个默认值:

int length = someString ?? "default".Length;

如果 someString 是 null,则整个表达式的结果是 0(因为 .Length 会返回字符串的长度),否则是 someString.Length 的值。

可空类型修饰符 (?)

  • 这个符号用于声明一个可空引用类型或值类型。当应用于引用类型时(如 string?),它表示该变量可以存储 null 值,而不仅仅是非空引用。
  • 使用案例:

    string? nullableString = null; // 可以为 null 的字符串

当然,可空类型修饰符 (?) 在 C# 中的应用不仅仅局限于声明可以为 null 的变量,还可以结合 null-conditional 运算符一起使用,进行更便捷的条件访问和方法调用。这里有一个例子:
 

int? value = GetNullableInt(); // 假设这个方法可能返回一个整数或 null

// 使用 null-conditional 运算符 ?. 来安全地访问成员或调用方法
// 如果 value 为 null,则整个表达式结果也为 null,不会抛出 NullReferenceException
int? doubledValue = value?.GetValueOrDefault() * 2;

// 或者在链式调用中使用它来避免空引用异常
string message = value.HasValue ? $"The value is {value.Value}" : "No value provided";
string safeMessage = value?.ToString() ?? "No value provided"; // 如果 value 为 null,则使用默认消息

// 对于集合类,也可以安全检查其元素
List<int>? numbers = GetNullableListOfNumbers();
int firstNumberOrDefault = numbers?.FirstOrDefault(); // 如果 numbers 为 null,则结果为 null
```

在这段代码中,`?.` 是 null-conditional 运算符,与可空类型修饰符一同作用时,它允许我们在访问成员或调用方法时进行安全的条件检查,如果前面的对象是 null,则整个表达式会立即停止计算并返回 null,而不会尝试对 null 引用执行操作导致运行时错误。

总结

  • ? 运算符:用于安全地检查引用类型变量是否为 null,并避免执行可能引发异常的代码块。如果变量为 null,整个表达式的结果也是 null
  • ?? 运算符:用于为可能为 null 的变量提供一个默认值。如果左侧的操作数为 null,则返回右侧的操作数作为结果。
  • 可空类型修饰符 :这个符号用于声明一个可空引用类型或值类型,表示该变量可以存储 null 值,而不仅仅是非空引用

欢迎阅读:

50个开发必备的Python经典脚本(1-10)

50个开发必备的Python经典脚本(11-20)

50个开发必备的Python经典脚本(21-30)

50个开发必备的Python经典脚本(31-40)

50个开发必备的Python经典脚本(41-50)

50个开发必备的Python经典脚本(1-10)

50个开发必备的Python经典脚本(11-20)

50个开发必备的Python经典脚本(21-30)

50个开发必备的Python经典脚本(31-40)

50个开发必备的Python经典脚本(41-50)

相关推荐

  1. C/C++ 引用指针区别使用场景

    2023-12-31 06:54:06       9 阅读
  2. externstatic使用区别

    2023-12-31 06:54:06       23 阅读
  3. define与typedef区别使用

    2023-12-31 06:54:06       8 阅读
  4. WebpackRollup区别使用场景、如何选择

    2023-12-31 06:54:06       28 阅读

最近更新

  1. TCP协议是安全的吗?

    2023-12-31 06:54:06       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2023-12-31 06:54:06       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2023-12-31 06:54:06       19 阅读
  4. 通过文章id递归查询所有评论(xml)

    2023-12-31 06:54:06       20 阅读

热门阅读

  1. 微服务(4)

    2023-12-31 06:54:06       36 阅读
  2. LeetCode每日一题.03(外观数列)

    2023-12-31 06:54:06       39 阅读
  3. 【论文阅读】Self-Paced Curriculum Learning

    2023-12-31 06:54:06       32 阅读
  4. python:PyCharm更改.PyCharm配置文件夹存储位置

    2023-12-31 06:54:06       41 阅读
  5. vue 使用AES加密

    2023-12-31 06:54:06       39 阅读
  6. Vue 2 将于 12 月 31 日到达生命周期终点

    2023-12-31 06:54:06       36 阅读
  7. html 表格 笔记

    2023-12-31 06:54:06       35 阅读