c# int? 是什么意思

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); // ❌ 崩溃
正确做法是:

  • 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,但用对了,它比任何注释都更能守住业务边界。