C# 可空类型(Nullable)
可空类型就是允许值类型(如 int、bool、DateTime)可以有一个没有值的状态(即 null)。
在 C# 中,像 int、float、bool 等都是值类型(Value Types),默认情况下它们不能为 null。
例如以下赋值就会编译错误:
int a = null; // 编译错误
但是使用 可空类型之后就可以:
int? a = null; // 合法
这时 a 的类型其实是:
Nullable<int>
int? 是 Nullable<int> 的语法糖(简写形式)。
单问号 ? 与双问号 ?? 的区别
| 运算符 | 名称 | 用途 | 示例 |
|---|---|---|---|
? |
可空类型标识符 | 让值类型可以为 null |
int? i = 3; 等价于 Nullable<int> i = new Nullable<int>(3); |
?? |
空合并运算符(Null-Coalescing Operator) | 当变量为 null 时提供默认值 |
int result = i ?? 0; |
例如:
int i; // 默认值为 0 int? ii; // 默认值为 null
C# 可空类型(Nullable)
C# 提供了一个特殊的数据类型:nullable 类型(可空类型)。
可空类型可以表示其基础值类型的正常范围内的值,再加上一个 null 值。
例如:
Nullable<int> x = null; // 可空的 Int32 Nullable<bool> flag = true; // 可空的布尔
Nullable<Int32> 变量可以被赋值为:
-2,147,483,648~2,147,483,647之间的任意整数;- 或者
null。
类似地,Nullable<bool> 可以被赋值为:
true;false;- 或
null。
可空类型的声明语法
<data_type>? <variable_name> = null;
例如:
int? age = null; double? temperature = 36.6; bool? isActive = new bool?();
下面的实例演示了可空数据类型的用法:
实例
using System;
namespace CalculatorApplication
{
class NullablesAtShow
{
static void Main(string[] args)
{
int? num1 = null;
int? num2 = 45;
double? num3 = new double?();
double? num4 = 3.14157;
bool? boolval = new bool?();
// 显示值
Console.WriteLine("显示可空类型的值: {0}, {1}, {2}, {3}",
num1, num2, num3, num4);
Console.WriteLine("一个可空的布尔值: {0}", boolval);
Console.ReadLine();
}
}
}
namespace CalculatorApplication
{
class NullablesAtShow
{
static void Main(string[] args)
{
int? num1 = null;
int? num2 = 45;
double? num3 = new double?();
double? num4 = 3.14157;
bool? boolval = new bool?();
// 显示值
Console.WriteLine("显示可空类型的值: {0}, {1}, {2}, {3}",
num1, num2, num3, num4);
Console.WriteLine("一个可空的布尔值: {0}", boolval);
Console.ReadLine();
}
}
}
当上面的代码被编译和执行时,它会产生下列结果:
显示可空类型的值: , 45, , 3.14157 一个可空的布尔值:
Null 合并运算符( ?? )
空合并运算符(??)用于为 可空类型 或 引用类型 定义一个默认值。
当左侧的值为 null 时,?? 返回右侧的默认值。
基本语法:
<表达式1> ?? <表达式2>
说明:
- 如果
<表达式1>不为 null,返回<表达式1>; - 否则返回
<表达式2>。
实例
using System;
namespace CalculatorApplication
{
class NullablesAtShow
{
static void Main(string[] args)
{
double? num1 = null;
double? num2 = 3.14157;
double num3;
num3 = num1 ?? 5.34; // num1 如果为空值则返回 5.34
Console.WriteLine("num3 的值: {0}", num3);
num3 = num2 ?? 5.34;
Console.WriteLine("num3 的值: {0}", num3);
Console.ReadLine();
}
}
}
namespace CalculatorApplication
{
class NullablesAtShow
{
static void Main(string[] args)
{
double? num1 = null;
double? num2 = 3.14157;
double num3;
num3 = num1 ?? 5.34; // num1 如果为空值则返回 5.34
Console.WriteLine("num3 的值: {0}", num3);
num3 = num2 ?? 5.34;
Console.WriteLine("num3 的值: {0}", num3);
Console.ReadLine();
}
}
}
当上面的代码被编译和执行时,它会产生下列结果:
num3 的值: 5.34 num3 的值: 3.14157
可空类型的常用属性和方法
| 成员 | 说明 | 示例 |
|---|---|---|
.HasValue |
判断变量是否有值 | if (num.HasValue) |
.Value |
获取实际值(若为 null 会抛异常) | int x = num.Value; |
.GetValueOrDefault() |
获取值或默认值(默认 0) | num.GetValueOrDefault() |
?? |
空合并运算符(提供默认值) | int result = num ?? 100; |
实际应用场景
在处理数据库或外部数据时,可空类型尤其常用。
例如:数据库表中的字段可能为空。
| 用户ID | 年龄 | 是否激活 |
|---|---|---|
| 1 | 28 | true |
| 2 | null | false |
使用可空类型:
int? age = GetUserAgeFromDB(2);
if (age == null)
Console.WriteLine("年龄未知");
else
Console.WriteLine($"用户年龄:{age}");
小结
| 功能 | 示例 | 说明 |
|---|---|---|
| 定义可空类型 | int? x = null; |
等价于 Nullable<int> |
| 判断是否有值 | x.HasValue |
判断变量是否已赋值 |
| 获取值 | x.Value |
若为 null 会抛异常 |
| 获取默认值 | x ?? 0 |
若为 null 返回默认值 |
| 默认值方法 | x.GetValueOrDefault(10) |
若为 null 返回 10 |
C# 8.0 的"可空引用类型"
从 C# 8.0 开始,引入了 可空引用类型(Nullable Reference Types),它与本文讲的 可空值类型(Nullable Value Types) 不同:
| 类型 | 示例 | 含义 |
|---|---|---|
| 可空值类型 | int? |
值类型可为 null(运行时支持) |
| 可空引用类型 | string? |
编译器层面的静态检查(不会改变运行时行为) |
菜鸟先飞
137***7781@qq.com
参考地址
num3 = num1 ?? 5.34; // num1 如果为空值则返回 5.34 Console.WriteLine("num3 的值: {0}", num3); num3 = num2 ?? 5.34; Console.WriteLine("num3 的值: {0}", num3);C# 中两个问号的作用是判断??左边的对象是否为 null,如果不为 null 则使用 ?? 左边的对象,如果为 null 则使用 ?? 右边的对象。
比如:
如果 b 为 null,则 a = c,如果 b 不为 null,则 a = b。
菜鸟先飞
137***7781@qq.com
参考地址
movin2333
mov***mind@163.com
?? 可以理解为三元运算符的简化形式:
movin2333
mov***mind@163.com