.Net6 生成的项目, 默认会启用 nullable 检查, 这样会大大避免 NullReferenceException?异常,
csproj 文件设置,
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
Nullable 的取值有 enable/disable/warnings/annotations 4种, 4种类型涉及两个维度, 警告上下文和注解上下文的开启,?
enable: 意义很明确, 启用最严格的方式, .net 6 默认方式.? 即编译器对表达式推断和声明不符合, 将会报编译错误.?
disable: 老项目默认方式, 即编译器不对nullable做任何推断, 也不会有任何警告.?
warnings: 即关闭注解上下文, 仅仅开启警告上下文, 简单理解: 编译器不对引用类型变量做推断,? 仅对值类型做简单推断, 违反nullable规则, 仅仅报 warning.?
annotations:?编译器对引用类型变量自行推断, 但不做警告.?
实际项目的问题:
问题1: 我们能确定赋值不会为null, 但编译器推断为空, 怎么调教编译器呢?
方案: 在代码中加上下面的方法即可.?
ArgumentNullException.ThrowIfNull(keyValuePairs);
问题2:? [DisallowNull] 注解和 T 的区别, [AllowNull] 和? T? 和Nullable<T> 的区别:??
[DisallowNull] string a1="a" ;? ?string a2="a";?
上面代码在C#8是没有区别的,??[DisallowNull] 常用于泛型类定义.
[AllowNull] string a1="a" ;? ?string? a2="a";? Nullable<string> a3="a";
上面代码在C#8是没有区别的,? [AllowNull]?常用于泛型类定义.
问题3: 强制干预编译器赋null值?
string a = null; // warning
string b = null!; // ok
string c = default!; // ok
问题4: 如何为老项目启用nullable检查
csproj文件中, 启用nullable检查,?
然后先为每个cs文件加上下面的指令
#nullable disable
然后一个一个文件开启, 并修正代码.?
=================================
参考
=================================
C# 8: Nullable Reference Types - Meziantou's blog