int?是 C# 中表示「可为空的整数」的语法糖,本质是
Nullable<int></int>结构体,它不是引用类型,也不是装箱后的 int,而是一个带状态标记的值类型。
为什么不能直接用 int
表示“没值”?
普通
int是值类型,默认值永远是
0——哪怕你忘了赋值,编译器也会悄悄塞个
0进去:
int x;<br>Console.WriteLine(x); // 输出 0这在业务中很危险:用户年龄字段没填,数据库存的是
NULL,但 C# 一读成
0,就变成“刚出生”,语义全错。
int?的默认值是
null,明确表达“未知/未填写/不存在” 它内部只多存了一个
bool _hasValue字段,没额外堆内存开销 它仍是栈上分配的值类型,不会触发 GC 或装箱(除非你显式转成
object)
int?
怎么安全取值?别掉进 Value
异常坑里
直接访问
Value属性会抛
InvalidOperationException(当它为
null时):
int? age = null;<br>Console.WriteLine(age.Value); // ❌ 崩溃正确做法是: 用
HasValue判断:
if (age.HasValue) { ... age.Value ... }
用 C# 7+ 的模式匹配:if (age is int actualAge) { ... }
用空合并运算符 ??提供默认值:
int safeAge = age ?? -1;用
GetValueOrDefault():
int safeAge = age.GetValueOrDefault(-1);
和数据库、API、前端交互时,int?
几乎是刚需
真实场景中,“可选数字字段”太常见了:
// 数据库映射(EF Core)<br>public int? Height { get; set; } // 对应 SQL Server 的 INT NULL<br><br>// Web API 接收 JSON(用户可能不传该字段)<br>{ "name": "Alice" } // Height 缺失 → 自动绑定为 null<br><br>// 前端表单未填写 → 后端收到 null 而非 0
如果硬用 int,反序列化会失败或默认塞
0,掩盖业务逻辑漏洞 ORM(如 EF Core)默认把数据库
INT NULL映射为
int?,强行改
int会导致运行时报错 ASP.NET Core Model Binding 对
int?天然支持
null输入;对
int则返回 400 Bad Request
关键点就一个:int?
不是“更松的 int
”,而是语义上完全不同的类型——它把“有值/无值”这个业务状态,原生编码进了类型系统里。漏判 null
是常见 bug,但用对了,它比任何注释都更能守住业务边界。
