c# 中的可空类型 nullable

来源:这里教程网 时间:2026-02-21 17:36:01 作者:

什么是
Nullable<t></t>
,它和
T?
是一回事吗

是的,

T?
Nullable<t></t>
的语法糖,仅适用于值类型(如
int
DateTime
bool
)。引用类型(如
string
List<int></int>
)本身就能为
null
,所以
string?
在 C# 8+ 中表示“可为空引用类型”,和值类型的
int?
语义不同,底层机制也完全不同。

关键区别在于:值类型加

?
后,编译器生成的是
Nullable<int></int>
结构体,它包含两个字段:
value
(真实值)和
hasValue
(是否已赋值),不是简单包装指针。

int? x = null;
→ 实际是
new Nullable<int>()</int>
hasValue == false
int? y = 5;
→ 实际是
new Nullable<int>(5)</int>
hasValue == true
typeof(int?) == typeof(Nullable<int>)</int>
true

解包时用
.Value
还是
.GetValueOrDefault()

直接访问

.Value
会在
hasValue == false
时抛出
InvalidOperationException
:“Nullable 对象必须具有一个值”。这在运行时才暴露,容易漏测。

.GetValueOrDefault()
更安全:未赋值时返回
T
的默认值(如
int?.GetValueOrDefault()
返回
0
),不抛异常。但要注意——它掩盖了“本应有值却缺失”的业务逻辑问题。

.Value
:适合你**确定有值**的场景(比如刚做过
HasValue
检查或来自可信输入)
.GetValueOrDefault()
:适合提供兜底值即可的场景(如数据库字段可能为空,前端显示“0”比崩溃好)
更推荐显式空合并:
int? x = ...; int actual = x ?? -1;
,语义清晰且不可空

== null
HasValue == false
等价吗

等价,但编译后行为略有差异。C# 编译器对

== null
做了特殊处理,会直接检查
hasValue
字段,和手动写
!x.HasValue
生成的 IL 几乎一致。

不过要注意:重载了

==
运算符的自定义结构体,如果错误地把
Nullable<t></t>
当普通类型处理,可能出错。标准值类型(
int
Guid
等)完全安全。

int? x = null; if (x == null) { ... }
✅ 安全、推荐
if (!x.HasValue) { ... }
✅ 语义更直白,尤其在复杂条件中
if (x.Equals(null)) { ... }
❌ 不推荐,调用虚方法,且
null
传入可能触发装箱

数据库读取时
DbDataReader.GetFieldValue<t>()</t>
GetInt32()
的坑

ADO.NET 的

GetFieldValue<t>()</t>
支持泛型,但对可空类型要求严格:若数据库列允许 NULL,且你传入
int?
,它能正确返回;但若误传
int
,遇到 NULL 会直接抛
InvalidCastException

而传统方法如

GetInt32()
GetString()
全部不支持 NULL —— 遇到 NULL 就炸,必须先用
IsDBNull()
判断。

var reader = cmd.ExecuteReader();
while (reader.Read())
{
    // ✅ 安全:自动处理 NULL
    int? age = reader.GetFieldValue<int?>(reader.GetOrdinal("age"));
<pre class='brush:php;toolbar:false;'>// ❌ 危险:NULL 时抛异常
// int age2 = reader.GetInt32(reader.GetOrdinal("age"));
// ✅ 传统方式(啰嗦但明确)
var dbVal = reader["age"];
int? age3 = dbVal == DBNull.Value ? null : (int?)dbVal;

}

最易被忽略的一点:Entity Framework Core 的

FromSqlRaw
或原生查询返回匿名类型时,若字段为 NULL,对应属性会是默认值(如
0
),而不是
null
—— 因为匿名类型属性推导基于非空类型。这时必须显式声明为可空,或改用元组/具体 DTO。

相关推荐