- Nullable reference types
- 文首
- 所有的引用数据类型均可以是可为空的。可为空引用类型,指的是在nullable aware context下,的一一系列技术,用于减少代码在运行的时候抛出System.NullReferenceException的可能性:
- 静态数据流分析,在解引用之前检查空引用
- 属性用于注记用编口,来帮助流分析定论null-state
- 开发者可注记变量是否意向null-state
- 默认情况下,null-state相关功能是禁用的,但从.NET 6开始在新工程中默认启用
- https://learn.microsoft.com/en-us/training/modules/csharp-null-safety中对此做出了解释
- 所有的引用数据类型均可以是可为空的。可为空引用类型,指的是在nullable aware context下,的一一系列技术,用于减少代码在运行的时候抛出System.NullReferenceException的可能性:
- Null state analysis
- null-state分析是静态的,一个变量要么是not-null,要么是maybe-null
- 是否not-null根据下面条件决定
- 变量被赋值另一个not-null值
- 变量与null做过比对
- 如果一个变量是maybe-null,那么就需要在解引用前检查其是否为null
- null-state分析不会进入调用的方法,所以无法知晓在方法中初始化的变量
- 通过Constructor chaining, or nullable attributes(例如
[MemberNotNull(nameof(Major))]
)可以化解此告警
- Attributes on API signatures
- 示例
public static bool IsNullOrWhiteSpace([NotNullWhen(false)] string message);
- 具体参考https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/attributes/nullable-analysis
- .NET5开始把API都注记了
- 示例
- Nullable variable annotations
- 类成员可以区分为nullable reference type或者nullable reference type
- 如果一个引用不应为空,那么默认为not-null,如果将null赋给此类成员,会受到编译器告警
- 如果一个引用可以为空,那么默认按照maybe-null处理
- nullable reference type的形式:
string? name;
- var声明的隐式局部变量也属于此类别
- 没有?,则为non-nullable reference
- 变量之后的null-forgiving操作符
!
将null-state设为not-null - 与nullable reference type相对照的nullable value type,类型为
System.Nullable<T>
string?
和stirng
的类型都是System.String
int?
的类型却是System.Nullable<System.Int32>
- nullable reference type是编译时的检查,可以被忽略的
- 类成员可以区分为nullable reference type或者nullable reference type
- Generics
- (暂略)
- Nullable contexts
- 可以用nullable annotation context控制编译器行为,其值如下
- disabled
- enabled
- warnings
- annotations
- 具体行为见文中表格
- 在csproj中使用https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/compiler-options/language来设置
- 也可以用指示来控制
- #nullable enable [warnings|annatations]
- #nullable disable [warnings|annatations]
- #nullable restore [warnings|annatations]
- 对生成的代码不适用,以下办法可以标识生成的代码
- .editorconfig, 指定
generated_code = true
- 放置
<auto-generated>
或<auto-generated/>
在头部 - 文件名以TemporaryGeneratedFile_开头
- 文件名以.designer.cs, .generated.cs, .g.cs, or .g.i.cs结尾
- .editorconfig, 指定
- .NET6的新建csproj中会指定
<Nullable>enable</Nullable>
开启null-state分析
- 可以用nullable annotation context控制编译器行为,其值如下
- Known pitfalls
- Arrays和structs中有可能出现漏检null-state的情况
- Structs
- 一个带有non-nullable reference types的struct允许直接赋值default,
- default会使nullable reference type的值为null,但使用时却不会告警
- 对于泛型参数,可能会出现检测不到null-state的情况
- 一个带有non-nullable reference types的struct允许直接赋值default,
- Arrays
- 下面的代码不会产生null告警
string[] values = new string[10]; string s = values[0]; Console.WriteLine(s.ToUpper());
- 下面的代码不会产生null告警
- 文首
- Nullable reference migrations
- 文首(略)
- Plan your migration
- 几种选择
- Nullable disable as the default
- Nullable enable as the default
- Nullable warnings as the default
- Nullable annotations
- 几种选择
- Understand contexts and warnings(过)
- Address warnings(过)
- Enable type annotations(过)
- Attributes extend type annotations(过)
- Next steps
- Language-Integrated Query (LINQ)
- Perform inner joins
- 文首
- inner join是这样一个操作,第一个合集中的每一个元素在匹配到的第二个合集每个元素中出现一次,如果第一个合集中的元素没有匹配到第二个合集中的元素,那么就不会出现
- 对应到C#的https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.join以及join句段
- 文中解释如何执行四种join操作
- Example - Simple key join
-
var query = from person in people join pet in pets on person equals pet.Owner select
-
- Example - Composite key join
- 可以在join的时候指定多个键项,形如:
join student in students on new { employee.FirstName, employee.LastName }
- 可以在join的时候指定多个键项,形如:
- Example - Multiple join(过)
- Example - Inner join by using grouped join(过)
- 注记
from a in table_a join b in table_b on a.id equals b.id
- 此处
a.id
和b.id
顺序不能反 - 且不能使用
Sql.Ext.SQLite().RowId(a)
的形式
- 此处
- 文首
- Perform left outer joins
- 似乎是在inner join之后使用DefaultIfEmpty来过滤出所需的记录
- Perform inner joins