.NET 源码学习 [数据结构-线性表1.2] 链表与 LinkedList<T>( 八 )


文章插图

.NET 源码学习 [数据结构-线性表1.2] 链表与 LinkedList<T>

文章插图
假如我们知道 obj 和 obj.ToString() 在这里一定不为空,那么就可以在 obj 与 ToString() 的结果后加上可空容忍运算符,将其转换为不可空类型,以此消除警告 。
.NET 源码学习 [数据结构-线性表1.2] 链表与 LinkedList<T>

文章插图
这样操作后,obj 不可再被赋值为 null 。
六、更多的可空特性【注:
1.     特性一般用来解决警告问题,并不能解决错误或进行强制类型转换 。
2.     特性的修饰更多地,只起到标识告知的作用 。】
需要引入命名空间
.NET 源码学习 [数据结构-线性表1.2] 链表与 LinkedList<T>

文章插图
(一) AllowNull性质:前置条件,即放在修饰对象前 。
作用:将不可为 null 的参数、字段或属性使其可以为 null 。【注意,这里的“不可为”指的是警告内容,不是数据类型上的不可为空】
举例:
.NET 源码学习 [数据结构-线性表1.2] 链表与 LinkedList<T>

文章插图
现在有一个字段,当通过属性获取字段值的时候 , 一定不会获得到 null,因为在 set 里面指定了非 null 的默认值 。然而在方法 Set() 里是允许设置 null 到这个属性,但属性 Msg 是不可为空的 。于是,为了解决警告的出现 , 要么将字段定义为可空,要么将这个加上特性 [AllowNull] 。这样 , 获取此字段的时候会得到非 null 值,但设置的时候却可以传递 null 。
.NET 源码学习 [数据结构-线性表1.2] 链表与 LinkedList<T>

文章插图

.NET 源码学习 [数据结构-线性表1.2] 链表与 LinkedList<T>

文章插图
即,将不可为空的属性 Msg 标记为可为空(可以传入空值),但传入空时会保持其默认值 。
大多数情况下,属性或 in、out 和 ref 参数需要此特性 。当变量通常为非 null 时,[AllowNull] 是最佳选择,但需要允许 null 作为前提条件 。
(二) 其余可空特性特性一般主要用于处理警告方面的问题,使得程序更加规范化,在此不作过多演示,更多内容,请参考下表(来自:C# 编译器解释的属性:可为 null 的静态分析 | Microsoft Learn)
Attribute
Category
含义
AllowNull
Precondition
不可为 null 的参数、字段或属性可以为 null 。
DisallowNull
Precondition
可为 null 的参数、字段或属性应永不为 null 。
MaybeNull
后置条件
不可为 null 的参数、字段、属性或返回值可能为 null 。
NotNull
后置条件
可为 null 的参数、字段、属性或返回值将永不为 null 。
MaybeNullWhen
有条件后置条件
当方法返回指定的 bool 值时 , 不可为 null 的参数可以为 null 。
NotNullWhen
有条件后置条件
当方法返回指定的 bool 值时 , 可以为 null 的参数不会为 null 。
NotNullIfNotNull
有条件后置条件
如果指定参数的自变量不为 null,则返回值、属性或自变量不为 null 。
MemberNotNull
方法和属性帮助程序方法
当方法返回时,列出的成员不会为 null 。
MemberNotNullWhen
方法和属性帮助程序方法
当方法返回指定的 bool 值时,列出的成员不会为 null 。
DoesNotReturn
无法访问的代码
方法或属性永远不会返回 。换句话说 , 它总是引发异常 。
DoesNotReturnIf
无法访问的代码
如果关联的 bool 参数具有指定值,则此方法或属性永远不会返回 。
七、特性 [Nullable]特性,在之前的文章中也讲述过,主要是进行修饰,使得对象具有某些额外性质 。
Nullable,属于内部密封类 NullableAttribute,派生自类 Attribute 。
.NET 源码学习 [数据结构-线性表1.2] 链表与 LinkedList<T>

文章插图
  • Line 13、22:该特性有两种表示方式,就是经常看到的:在括号里写上数字或一个数组

.NET 源码学习 [数据结构-线性表1.2] 链表与 LinkedList<T>

文章插图

.NET 源码学习 [数据结构-线性表1.2] 链表与 LinkedList<T>

文章插图
  • Line 28:最后均存储到名为 NullableFlags的 byte 数组中,据名称可以推测,每个不同的数字赋予了 Nullable 这个特性不同的额外功能 。
根据 C# 的编译器roslyn的GitHub页面(roslyn/nullable-metadata.md at main · dotnet/roslyn · GitHub):Each type reference in metadata may have an associated NullableAttribute with a byte[] where each byte represents nullability: 0 for oblivious, 1 for not annotated, and 2 for annotated. 也就是说,该数组中的有效值仅为0、1、2,且具有不同的含义 。【由于无法找到相关文档,也无法进行相关实验操作,数值所代表的含义在此暂不做分析 , 后续可能会补上】

推荐阅读