?.和??是C#中用于安全处理null的运算符:?.在对象非null时访问成员,否则返回null;??为null提供默认值;二者常组合使用,如int age = user?.Profile?.Age ?? 0。

在C#中,?.(空条件运算符)和??(空合并运算符)是专为安全处理可能为 null 的引用类型而设计的语法糖。它们让代码更简洁、可读性更高,同时避免了冗长的 if (obj != null) 检查。
?.:只在对象非null时才访问成员
当你不确定某个对象是否为 null,又想调用它的方法、属性或索引器时,用 ?. 可以避免运行时异常。如果左侧操作数为 null,整个表达式直接返回 null(或对应类型的默认值,如 int? 返回 null),不再执行右侧操作。
-
例如:
string name = person?.Name;—— 如果person是null,name就是null,不会抛出NullReferenceException - 支持链式调用:
var city = customer?.Address?.City;—— 任一环节为null,结果即为null - 可用于方法调用:
int? length = str?.Length;或str?.ToString();(返回null而非报错)
??:提供null时的默认值
?? 用于为可能为 null 的表达式指定一个“备选值”。只要左侧不为 null,就返回它;否则返回右侧的操作数(该值可以是字面量、变量或表达式)。
-
例如:
string displayName = person?.Name ?? "未知用户";—— 先用?.安全取名,再用??补默认值 - 右侧可以是复杂表达式:
var config = settings ?? LoadDefaultConfig();(仅当settings为null时才调用方法) - 注意:只对引用类型和可空值类型(如
int?)有效;普通int不能直接用??
组合使用:构建健壮的空值处理链
?. 和 ?? 经常一起出现,形成清晰、安全的默认值逻辑。这种组合几乎替代了传统“先判空再赋值”的模板代码。
-
int age = user?.Profile?.Age ?? 0;—— 即使user或Profile为null,也不会崩溃,最终得到0 -
IEnumerable—— 确保返回一个可用的集合tags = post?.Tags ?? Enumerable.Empty (); - 搭配
??=(空合并赋值)还能简化初始化:cache ??= new Dictionary();
基本上就这些。它们不是黑魔法,但确实让日常的空值防御变得轻量又自然——不复杂,但容易忽略。









