简化 null 检查:C# 中的 ?. 和 ?? 运算符

在 C# 中,处理 null 值是一个常见的挑战,尤其是当我们需要访问对象的属性或调用方法时。传统的做法是使用 if 语句手动进行 null 检查,但这往往会导致冗长且难以维护的代码。幸运的是,C# 提供了两种非常实用的运算符——?.(空条件运算符)和 ??(空合并运算符),可以让我们更优雅地处理 null 值,从而简化代码并提高可读性。

1. 空条件运算符 ?. —— 安全地访问对象成员

空条件运算符 ?. 允许你在访问对象成员时,自动判断对象是否为 null,如果是 null,则不会抛出 NullReferenceException 异常,而是直接返回 null。

示例:

class Person {
    public string Name { get; set; }
}

Person person = null;
string name = person?.Name;  // 如果 person 为 null,name 也为 null
Console.WriteLine(name);         // 输出:null

在这个例子中,我们无需显式检查 person 是否为 null。通过使用 ?. 运算符,程序会自动判断 person 是否为 null,如果是 null,Name 属性的访问将返回 null,并且程序不会抛出异常。

链式调用:

class Address {
    public string City { get; set; }
}

class Person {
    public Address Address { get; set; }
}

Person person = null;
string city = person?.Address?.City;  // 如果 person 或 Address 为 null,city 会是 null
Console.WriteLine(city);  // 输出:null

当涉及到多个嵌套的对象时,空条件运算符 ?. 使得代码变得更加简洁和安全。

2. 空合并运算符 ?? —— 提供默认值

空合并运算符 ?? 允许我们为可能为 null 的表达式提供一个默认值。当左侧的值为 null 时,?? 会返回右侧的默认值。

示例:

Person person = null;
string name = person?.Name ?? "未知";  // 如果 person?.Name 为 null,返回 "未知"
Console.WriteLine(name);  // 输出:未知

在这个例子中,如果 person?.Name 结果为 null,则 ?? 运算符会将 "未知" 作为默认值返回。这样,我们就避免了 null 值可能导致的错误,并能保证 name 始终有一个有效的值。

3. 结合使用 ?. 和 ?? 运算符

你还可以将 ?. 和 ?? 运算符结合使用,以进一步简化 null 检查和提供默认值。

示例:

class Person {
    public Address Address { get; set; }
}

class Address {
    public string City { get; set; }
}

Person person = null;
string city = person?.Address?.City ?? "未知城市";  // 如果 person?.Address?.City 为 null,返回 "未知城市"
Console.WriteLine(city);  // 输出:未知城市

通过这种方式,你可以在访问多个嵌套成员时,既能保证代码的简洁性,又能处理 null 值并提供合理的默认值。

总结

C# 中的 ?. 和 ?? 运算符极大地简化了 null 值的处理,减少了冗长的空值检查代码。?. 运算符让你能够安全地访问可能为 null 的对象成员,而 ?? 运算符则为 null 值提供了一个默认值。两者结合使用,可以让你写出更加简洁、易读、且不容易出错的代码。

如果你还不熟悉这些运算符,建议尽快在你的代码中应用它们,提升代码的质量和可维护性。

### C# 中 `?.` 操作符的作用与使用场景 在 C# 中,`?.` 是一种称为 **Null 条件运算符** 的语法结构[^3]。它的主要功能是在访问对象成员之前检查该对象是否为 null。如果对象为 null,则表达式的计算会短路并立即返回 null,而不会抛出 NullReferenceException。 以下是关于 `?.` 操作符的具体解释: #### 1. 基本概念 通过使用 `?.` 运算符,可以在调用属性、方法或索引器前安全地检测对象是否为 null。如果没有此操作符,在尝试访问一个 null 对象的成员时,程序可能会引发运行时异常 (NullReferenceException)。 #### 2. 使用示例 下面是一些常见的使用场景及其对应的代码示例: ##### 场景一:安全访问属性 假设有一个类 `Person` 及其子属性 `Address`,我们可以通过 `?.` 安全地获取嵌套属性而不必担心中间层为 null。 ```csharp public class Person { public string Name { get; set; } public Address HomeAddress { get; set; } } public class Address { public string City { get; set; } } ``` 传统写法(容易报错): ```csharp string city = person.HomeAddress.City; // 如果 person 或 HomeAddress 为 null,这里会抛出 NullReferenceException ``` 改进后的写法(使用 `?.`): ```csharp string city = person?.HomeAddress?.City; // 当 person 或 HomeAddress 为 null 时,city 将被赋值为 null 而不是抛出异常 ``` ##### 场景二:调用方法 同样适用于方法调用。如果目标对象可能为 null,可以直接在其上调用方法并通过 `?.` 防止潜在错误。 ```csharp List<int> numbers = null; int count = numbers?.Count() ?? 0; // 如果 numbers 为 null,则 Count 方法不会被执行,count 默认设置为 0 ``` ##### 场景三:组合多个 `?.` 可以连续多次应用 `?.` 来处理复杂的链式调用。 ```csharp var result = objA?.ObjB?.PropertyC; // 若 objA 或 ObjB 为 null,则 PropertyC 不会被访问,result 返回 null ``` #### 3. 结合其他操作符 有时可将 `?.` 与其他操作符一起使用来增强灵活性。例如,配合空合并运算符 (`??`) 提供默认值。 ```csharp string name = employee?.Manager?.Name ?? "No Manager"; // 如果 employee.Manager 不存在或者 Manager.Name 未定义,默认显示"No Manager" ``` --- ### 总结 `?.` 操作符简化了对可能存在 null 的对象进行成员访问的过程,从而减少了显式条件判断的需求,并提高了代码的安全性简洁度。 ```csharp class Program { static void Main() { Person p = new Person(); Console.WriteLine(p?.HomeAddress?.City); // 输出 null,因为 HomeAddress 未初始化 var list = default(List<string>); int size = list?.Count ?? -1; // 输出 -1 表明列表为空 } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

威哥说编程

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值