int? 是 C# 中表示可为空整数的值类型,本质为 Nullable 结构体,通过 _hasValue 字段标识是否含有效值,避免用 0 误表“未填写”,支持安全取值(HasValue、??、模式匹配等),广泛用于数据库映射、API 交互等需区分“有值/无值”的场景。

int? 是 C# 中表示「可为空的整数」的语法糖,本质是 Nullable 结构体,它不是引用类型,也不是装箱后的 int,而是一个带状态标记的值类型。
为什么不能直接用 int 表示“没值”?
普通 int 是值类型,默认值永远是 0——哪怕你忘了赋值,编译器也会悄悄塞个 0 进去:
int x;这在业务中很危险:用户年龄字段没填,数据库存的是
Console.WriteLine(x); // 输出 0
NULL,但 C# 一读成 0,就变成“刚出生”,语义全错。
-
int?的默认值是null,明确表达“未知/未填写/不存在” - 它内部只多存了一个
bool _hasValue字段,没额外堆内存开销 - 它仍是栈上分配的值类型,不会触发 GC 或装箱(除非你显式转成
object)
int? 怎么安全取值?别掉进 Value 异常坑里
直接访问 Value 属性会抛 InvalidOperationException(当它为 null 时):
int? age = null;正确做法是:
Console.WriteLine(age.Value); // ❌ 崩溃
NetShopForge是一款强劲的B2C的网上购物软件,利用她我们能建立起强劲的、自由的、安全的购物平台。 维博软件以有这样的软件无比自豪,系统基于ASP.NET 2.0及SqlServer开发,充分享受新技术带来的乐趣。 软件综合了卖家,买家,程序员,设计者的头脑风暴,目的就是用户能建立风格不同的电子商务系统,使它显得更加与众不同。 如果您寻求一款能按您的思想随意发挥的网上购物软件,那么Net
- 用
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)
public int? Height { get; set; } // 对应 SQL Server 的 INT NULL
// Web API 接收 JSON(用户可能不传该字段)
{ "name": "Alice" } // Height 缺失 → 自动绑定为 null
// 前端表单未填写 → 后端收到 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,但用对了,它比任何注释都更能守住业务边界。









