C#中空合并运算符??与??=的区别及??=适用场景
C# 中空合并运算符 ?? 与 ??= 的用法及区别
?? 运算符的基础回顾
?? 是空合并运算符,逻辑很直接:判断左侧操作数是否为 null,不为 null 就返回左侧值,否则返回右侧的默认值。你给出的示例:
int? a = null; int b = a ?? 0; // b 的值为 0
注意左侧操作数必须是可空值类型或者引用类型。
什么时候用 ??= 运算符
??= 是 C# 7.3 引入的空合并赋值运算符,是 变量 = 变量 ?? 默认值 的简化写法,专门用来在变量为 null 时才给它赋值,不会覆盖已有非 null 的值,以下是最适合用它的场景:
给变量设置默认值(不覆盖已有值)
如果你的变量可能为 null,但你只想在它确实是 null 的时候才赋予默认值,用??=比写完整的??赋值更简洁。比如:List<int> numbers = null; numbers ??= new List<int>(); // 因为 numbers 是 null,所以创建新列表 // 如果 numbers 之前已经有元素,这行代码不会做任何操作换成??的写法是
numbers = numbers ?? new List<int>();,显然??=更清爽。延迟初始化对象
在类的字段初始化、缓存场景里,经常需要“第一次使用才创建对象”的逻辑,用??=能完美实现:private Dictionary<string, object> _dataCache; public void CacheData(string key, object value) { _dataCache ??= new Dictionary<string, object>(); // 仅当缓存为 null 时初始化 _dataCache[key] = value; }这样每次调用方法时,不会重复创建字典实例,只有第一次(缓存未初始化)才执行创建,避免不必要的资源消耗。
配置类属性的默认值
在处理配置对象时,你可能希望保留外部已经设置的属性值,只给未设置(为 null)的属性赋默认值:public class ServiceConfig { public string ApiUrl { get; set; } public int RetryCount { get; set; } } var config = new ServiceConfig(); config.ApiUrl ??= "https://api.example.com/v1"; // 仅当 ApiUrl 为 null 时赋值
两者的核心区别
- ?? 是取值运算符:它不会修改左侧变量本身,只是返回一个结果,需要你手动把结果赋值给变量;而??= 是赋值运算符,直接修改左侧变量(仅当左侧为 null 时)。
- 代码对比:
int? x = null; int y = x ?? 10; // x 仍然是 null,y 等于 10 x ??= 10; // x 现在被赋值为 10
内容的提问来源于stack exchange,提问作者Muhammad Bilal
相关产品推荐
相关产品推荐

