CodeGym /课程 /C# SELF /值类型的Nullable类型

值类型的Nullable类型

C# SELF
第 14 级 , 课程 0
可用

1. 入门

想象一下这种情况:你在代码里存猫的数据。除了猫的年龄,你还想存点类似“没数据”、“年龄未知”这种状态。你可以存0,但0其实是个合法的年龄。

int age = 0; // 猫的年龄。但0到底是小猫还是“未知”?

问题在于,int只能存整数,没法表达“没数据”。如果年龄是字符串,那你可以赋null。但数字类型就不行:

int age = null; // 错误! 不能给int类型变量赋null

这是因为值类型(像struct,比如intdoubleDateTimebool)总得有个值。它们没有“空”的状态(跟引用类型不一样,引用类型的null就是没有对象)。

生活中的例子:
有时候程序员会想出“特殊值”来绕过这个限制,比如-1或者int.MaxValue表示“没值”。但这样又丑又麻烦,还容易把真实值和占位符搞混。

2. Nullable类型:可以为null的类型

思路

要是普通数字(其实所有值类型)也能存null就好了吧?
C#里这事儿靠一个特殊的包装类Nullable<T>搞定。这个类可以存一个T类型的值,也可以啥都不存(就是null)。

语法

int? age = null; // age变量可以是数字,也可以是null
?声明nullable类型

C#编译器看到这种写法,其实等价于:

Nullable<int> age = new Nullable<int>(); // age变量没有值

或者你想直接赋值:

Nullable<int> age = new Nullable<int>(42); // age存了42

所以,问号能把任何值类型变成它的nullable版本:

  • int?(其实就是Nullable<int>
  • double?
  • DateTime?
  • 还有各种struct都行

常用struct的Nullable包装

普通类型 Nullable类型 写法示例
int
int?
int? a = null;
double
double?
double? x = 3.14;
bool
bool?
bool? ok = null;
DateTime
DateTime?
DateTime? d = null;

你也可以写得更长,用包装类的写法:


Nullable<int> pages = null;
        
更长的写法

但写int?更短更酷。

3. 怎么用nullable类型

赋值和判断

null跟引用类型一样简单:

声明和赋值

int? temperature = null;
temperature = 25;

判断是不是null

怎么知道nullable类型里有没有值?

if (temperature != null)
{
    Console.WriteLine($"温度: {temperature}");
}
else
{
    Console.WriteLine("没有温度数据");
}

Nullable类型的属性:.HasValue.Value

nullable类型有两个重要属性:

  • .HasValue —— 如果变量有值(不是null)就返回true
  • .Value —— 变量的值(如果有,否则会抛异常)。
int? temperature = null;
if (temperature.HasValue) //不会抛异常!
{
    Console.WriteLine($"温度: {temperature.Value}°C");
}
else
{
    Console.WriteLine("温度未知");
}

这段代码没问题:temperature不是null,它里面存的是null。你随时可以用Nullable类型的HasValue属性。但如果你在没值的时候取.Value,就会抛InvalidOperationException。所以一定要先判断!

更简洁的输出写法

很多时候直接用nullable类型变量就行,C#自己会处理:

int? hours = null;
Console.WriteLine(hours); // 什么都不输出(就是空)
hours = 10;
Console.WriteLine(hours); // 输出10

4. 运算和nullable类型:算术、比较、类型转换

运算:会发生什么?

只要有一个操作数是nullable,结果也是nullable。
如果有一个操作数是null,结果也会是null

int? a = 5;
int? b = null;
int? sum = a + b; // sum == null

int? c = 10;
int? d = 15;
int? total = c + d; // total == 25

比较运算

nullable类型可以和普通数字比较:

int? score = null;
if (score > 0) Console.WriteLine("很棒的结果!");
else Console.WriteLine("没有结果"); // 会走这里

如果score是null,score > 0会是false

显式和隐式类型转换

  • 普通类型转nullable:自动搞定。
  • nullable转普通类型:只有不是null才行(否则抛异常)。
int? x = 3;
int y = x.Value; // 只要x不是null就OK

// 隐式转换
int? z = y;

5. Nullable和方法:参数和返回值

返回nullable值

如果方法不一定能返回结果,可以用nullable类型做返回值:

// 方法根据登录名找用户,找到就返回年龄,否则null
int? FindUserAge(string login)
{
    // ... 这里是查找逻辑
    return null; // 没找到
}

Nullable参数

参数也可以用nullable类型,表示“可能有,也可能没有”。

void PrintTemperature(int? temp)
{
    if (temp == null)
        Console.WriteLine("温度未知");
    else
        Console.WriteLine($"温度: {temp}度");
}
2
任务
C# SELF, 第 14 级, 课程 0
已锁定
Nullable类型:声明和检查
Nullable类型:声明和检查
2
任务
C# SELF, 第 14 级, 课程 0
已锁定
带有 nullable 类型的算术运算
带有 nullable 类型的算术运算
评论
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION