C#笔记——可为空值/引用类型
本文最后更新于:2023年9月7日 下午
可为空值类型
基本概念
可为空值类型T?表示其基础值类型T的所有值及额外的null值。比如bool?的值有:true、false和null,而普通的bool的值只有:true和false,因为基础值类型T本身不能是可为空的值类型。
任何可为空的值类型都是泛型System.Nullable<T>结构的实例,比如int?是System.Nullable<int>的实例。
声明和赋值
声明就是基础值类型后加一个?,赋值则跟基础值类型一样。
1 | |
检查可为空值类型的实例
使用只读属性Nullable<T>.HasValue来检查和获取可为空值类型变量的值:
1 | |
从可为空的值类型转换为基础类型
如果要将可为空值类型的值分配给不可以为空的值类型变量,则可以使用Null合并操作符??或者Nullable<T>.GetValueOrDefault(T)方法(此方法若不传递参数则使用基础值类型的默认值来替代null):
1 | |
也可以使用显式强制转换为不可为空的类型(注意如果可为空的值类型的值为null的话,显式强制转换将抛出InvaildOperationException异常):
1 | |
提升的运算符
预定义的一元运算符和二元运算符或值类型T支持的任何重载运算符也受相应的可为空值类型T?支持。只要有一个操作数为null,那么运算的结果就是null。这里的特殊例子是bool?类型,详情可以参考官方文档。
1 | |
对于比较运算符>、>=、<、<=,只要有一个操作数为null,返回的结果就是false。
对于相等运算符==,如果两个操作数都为null,则结果为true;如果只有一个操作数为null,则结果为false。
对于不等运算符!=,参考相等运算符==。
装箱和取消装箱
给可为空的值类型的实例进行装箱操作,实质上是对基础值类型T的对应值装箱:
- 如果
HasValue返回false,则生成空引用。 - 如果
HasValue返回true,则基础值类型T的对应值将装箱,而不对Nullable<T>的实例进行装箱。
如何确定可为空的值类型
下面的示例演示了如何确定System.Type实例是否表示已构造的可为空值类型:
1 | |
严格按照上面写就好了,先使用typeof运算符获取System.type实例,再使用Nullable.GetUnderlyingType方法来检查。如果想知道为什么,简洁来说就是Object.GetType方法获取到的Type实例无法区分,is运算符无法确定,详细的原因参考官方文档。
可为空引用类型
用来干什么?——用于降低代码导致运行时引发System.NullReferenceException异常(尝试取消引用空对象引用时引发的异常)的可能性。
1 | |
在可为null的感知上下文中:
- 引用类型
T的变量必须用非null值进行初始化,并且不能为其分配可能为null的值。 - 引用类型
T?的变量可以用null进行初始化,也可以分配null,但在取消引用之前必须对照null进行检查。 - 类型为
T?的变量m在应用null包容运算符(!)时被认为是非空的,如m!。
限制
- 可为空的引用类型不能用作基类或实现的接口
- 可为空的引用类型不能用于任何对象创建
- 可为空的引用类型不能用于任何类型测试表达式
- 可为空的引用类型不能是成员访问表达式的类型
1 | |

希望本文章能够帮到您~