直接用 == null 判断引用类型最安全
对引用类型(如
string、
object、自定义类实例),
==运算符默认调用
ReferenceEquals,能准确识别是否为
null。这是最常用也最不易出错的方式。 不要用
.Equals(null)—— 会抛
NullReferenceException避免重载了
==的自定义类型(极少见),此时应优先查文档或改用
ReferenceEquals(obj, null)
string是特例:它重载了
==,但行为仍符合预期(
"" == null为
false),所以放心用
值类型不能为 null,但可空值类型(Nullable)要特殊处理
int、
DateTime等非泛型值类型永远不为
null,编译器甚至不允许写
int x = null;。但
int?(即
Nullable<int></int>)可以,判断方式不同: 用
obj == null对
int?是合法且推荐的(编译器自动转换为
HasValue == false) 也可显式调用
obj.HasValue,语义更清晰,尤其在复杂条件中 别用
obj == default(int?)—— 虽然结果相同,但可读性差,且容易和默认值逻辑混淆
使用 ?? 和 ?. 避免重复判空
频繁判空时,C# 提供了更简洁的语法,本质仍是基于
null判断,但大幅减少样板代码:
var name = person?.Name ?? "Unknown":若
person为
null,整个表达式短路,直接取右值
list?.Count:若
list为
null,返回
null(如果
Count是
int,则需配合
??或转为
int?) 注意
?.只对引用类型或可空值类型有效;对普通
int用
?.ToString()会编译失败
警惕装箱导致的意外 null 判断失效
当把可空值类型(如
int?)赋给
object时会发生装箱,若其值为
null,装箱后是真正的
null引用;但若你再把它拆箱回
int?,必须确保类型一致,否则会抛异常:
int? x = null; object o = x; // 装箱 → o 为 null int? y = (int?)o; // 正确:拆箱回 int? int z = (int)o; // 错误:拆箱为 int 会抛 InvalidCastException
这种场景下,
o == null返回
true是对的,但后续操作必须匹配原始可空类型,否则判空通过后仍可能崩溃。
