在 C# 中 Nullable Reference Types 使用属性NotNullWhen

承上文 在 C# 中 Nullable Reference Types 使用属性AllowNull

继续探讨...

使用属性 NotNullWhen

假设我们有一个方法检查变数是否为 null。根据此检查的结果,该方法返回 bool 类型的值。

示例:

bool CheckNotNull(object? obj){  return obj != null;}

使用此方法:

public void Foo(object? obj1){  object obj2 = new object();  if (CheckNotNull(obj1))    obj2 = obj1;}

编译器将对上面的程式码发出警告:
http://img2.58codes.com/2024/201525691bHAzODIWH.jpg

警告讯息如下:

警告CS8600正在将 Null 常值或可能的 Null 值转换为不可为 Null 的型别。

但这段程式码NULL情况是不可能发生的,因为已经先检查确保不为空。问题是编译器无法理解这个情况,所以我们必须帮助它。

我们可以加入属性 NotNullWhen 来更改 CheckNotNull() 的签名:

bool CheckNotNull([NotNullWhen(true)]object? obj)

此属性将将参数的 Null 状态与 检查方法的回传值 相关联。
用来向编译器“解释”,如果方法返回 true,则该参数 obj 具有值非空。


这个NotNullWhen 属性还有一些特性如下:

若使用out修饰符

bool GetValidOrDefaultName([NotNullWhen(true)] out string? validOrDefaultName,                            string name){  if (name == null)  {    validOrDefaultName = name;    return true;  }  else  {    validOrDefaultName = "defaultName";    return false;  }}

编译器将对上面的程式码发出警告:
http://img2.58codes.com/2024/20152569X9VYLsxsrd.jpg

警告讯息如下:

警告CS8762参数 'validOrDefaultName' 在以 'true' 结束时必须具有非 Null 值。

这里警告非常合理,因为你用了NotNullWhen属性向编译器“解释”,
如果方法返回 true,则该参数 validOrDefaultName 具有值非空。
但在此段程式码中,当 validOrDefaultName 为 null 时,该方法返回 true。
除非你在条件中使用了 “!=” 而不是 “==” 运算符


若使用ref修饰符

bool SetDefaultIfNotValid([NotNullWhen(true)] ref string? name){  if (name == null)    return true;  name = "defaultName";  return false;}

编译器将对上面的程式码发出警告:
http://img2.58codes.com/2024/20152569AeEYUFsnP7.jpg

警告讯息如下:

警告CS8762参数 'name' 在以 'true' 结束时必须具有非 Null 值。

与前面的例子类似,这里警告非常合理,因为你用了NotNullWhen属性向编译器“解释”,
如果方法返回 true,则该参数 name 具有值非空。
因为你使用了 '==' 而不是 '!=' 运算符。


若不使用修饰符

bool CheckingForNull([NotNullWhen(true)] string? name){  if (name == null)    return true;  Console.WriteLine("name is null");  return false;}

这里的情况与之前的案例类似。按照前面例子的逻辑,这里应该也发出警告讯息:

Parameter 'name' must have a non-null value when exiting with 'true'。

但是,没有警告。
http://img2.58codes.com/2024/20152569GLUSay25sa.jpg
微软这样的逻辑其实很怪。 WHY???
什么原因造成的? 不好说~

也许这里就是所谓一些不显而易见的地方

了解更多:NotNullWhenAttribute Class


下一篇
在 C# 中 Nullable Reference Types 使用属性NotNullIfNotNull


关于作者: 网站小编

码农网专注IT技术教程资源分享平台,学习资源下载网站,58码农网包含计算机技术、网站程序源码下载、编程技术论坛、互联网资源下载等产品服务,提供原创、优质、完整内容的专业码农交流分享平台。

热门文章