可为 null 的值类型表示其基础值类型T?T的所有值,以及附加null值。 类型的 int? 变量包含任何整数或 null 表示“无值”。
值类型,例如 int、bool 和 DateTime,默认情况下不能保留 null。 此行为非常有效,可防止出现许多错误。 但是,当某个值可能真正不存在时,此限制会产生问题。 常见方案是从数据库读取的:整数列可能包含数字,或者它根本不包含任何值(NULL 在 SQL 中)。 普通 int 不能表示这种缺席,但 int? 可以。
声明可以为 null 的值类型
追加 ? 到任何值类型,使其可为 null:
int? age = null; // integer with no value yet
double? price = 9.99; // nullable double with a value
bool? isActive = null; // boolean with no value
age = 30; // assign a value later
int?[] scores = [100, null, 85, null, 72]; // array with absent entries
可以为 null 的值类型的默认值是null,而不是其基础类型的默认值。
检查某个值是否存在
检查可为 null 的值类型并提取其值的建议方法是采用 类型模式:
int? temperature = 72;
if (temperature is int degrees)
{
Console.WriteLine($"Temperature is {degrees}°F.");
}
else
{
Console.WriteLine("Temperature is not recorded.");
}
// Output: Temperature is 72°F.
模式is int degrees仅当temperature非null时匹配,同时将其值绑定到degrees。 您可以在一步中同时进行 null 检查和值提取。
或者,使用 HasValue 和 Value 属性:
int? count = 42;
if (count.HasValue)
{
Console.WriteLine($"Count is {count.Value}.");
}
else
{
Console.WriteLine("Count has no value.");
}
// Output: Count is 42.
对新代码,首选 is T value 模式。 它引入了一个新的不可为 null 的变量,该变量的作用域限定于匹配分支,这样意图更加清晰,并消除了在 null 检查之外意外使用 Value 的任何风险,否则会引发 InvalidOperationException 异常。
还可以直接与 null 进行比较。
int? quantity = null;
if (quantity != null)
{
Console.WriteLine($"Quantity: {quantity.Value}");
}
else
{
Console.WriteLine("Quantity is not set.");
}
// Output: Quantity is not set.
获取具有回退功能的值
当需要从可为 null 的类型中提取不可为 null 的值时,请使用 GetValueOrDefault 运算符或 null 合并 ?? 运算符。
int? rating = null;
int result1 = rating.GetValueOrDefault(); // 0 (default for int)
int result2 = rating.GetValueOrDefault(-1); // -1 (specified fallback)
Console.WriteLine(result1); // 0
Console.WriteLine(result2); // -1
rating = 5;
int result3 = rating.GetValueOrDefault(-1); // 5 (actual value)
Console.WriteLine(result3); // 5
?? 运算符通常更简洁:
int? priority = null;
int effective = priority ?? 0; // 0 because priority is null
Console.WriteLine(effective); // 0
priority = 3;
effective = priority ?? 0; // 3 because priority has a value
Console.WriteLine(effective); // 3
这两种方法在某个值存在时返回该值,当不存在值时返回您指定的回退值。
具有可为 null 的值类型算术
运算符针对可为 null 值类型的算术和比较操作进行了提升:当任一操作数为 null 时,结果为null,而不是产生错误。
int? a = 10;
int? b = 20;
int? c = null;
int? sum = a + b; // both non-null: result is 30
int? product = a * c; // one operand is null: result is null
Console.WriteLine(sum); // 30
Console.WriteLine(product.HasValue); // False — null propagates through arithmetic
默认情况下,Null 通过算术传播。 为了防止 null 结果进一步传播,请在将其用于计算之前提取具有 ?? 或 GetValueOrDefault 的值。