C# 9.0 新特性预览 – 空参数校验

C# 9.0 新特性预览 - 空参数校验

前语
跟着 .NET 5 发布日期的日益接近,其对应的 C# 新版本已确定为 C# 9.0,其间新添加的特性(或语法糖)也已根本确定,本系列文章将向我们展现它们。

目录
[C# 9.0 新特性预览 - 类型推导的 new]
[C# 9.0 新特性预览 - 空参数校验]
[C# 9.0 新特性预览 - Lambda 中的弃元]
[C# 9.0 新特性预览 - Record 类型]
[C# 9.0 新特性预览 - 形式匹配的改进]
[C# 9.0 新特性预览 - 其他小的改变]

简洁的空参数校验 (Simplified Null Argument Checking)
意图
这个特性首要是为了更简洁的查看办法的参数是否为 null 并抛出 ArgumentNullExceptiony 反常。

语法
语法很简单,在参数名后加个叹号即可:

void M(string name!) {

...

}
以上代码会被翻译为:

void M(string name) {

if (name is null) {
throw new ArgumentNullException(nameof(name));
}
...

}
想必有些同学现已从上面代码看出来了,这个生成的空校验,仅仅校验参数是否为 null,这也就意味着它无法在值类型上运用,以下代码将报错:

// Error: 无法在值类型参数上运用!操作符
void G(T arg!) where T : struct {

}
当然,可空的值类型是能够的,可是编译器会提示一条正告,提示你在可空类型进步行了空查看:

// Warning: 将显式null查看与可为null的类型结合运用
void M(int? x!) {
}
相似的,在参数具有默认值的情况下,也会提示正告

// Warning: 参数 'x' 进行了空查看可是它默以为空
void M(string x! = null) {
}

结构办法的场景
在结构办法的场景下,空参数校验将发作在任何其他代码的前面,包含:

对其他结构办法的链式调用,即 this() 或 base()
在结构办法内的隐式字段初始化
举个比如:

class C {

string field = GetString();
C(string name!): this(name) {
...
}

}
以上代码会大致翻译为以下伪代码

class C {

C(string name)
if (name is null) {
throw new ArgumentNullException(nameof(name));
}
field = GetString();
:this(name);
...

}

Lambda 的场景
这个特性在 lambda 中也能够运用

void G() {

Func<string, string> s = x! => x;

}

不能够运用的场景
这个特性只能用于有办法体的办法中,也就意味着它不能用于笼统办法、接口、托付和部分办法。
以下代码编译器会报错:

interface C
{

public int M(string x!);// ERROR

}
不能用于特点。由于特点 setter 中的 value 是隐式的,不会出现在参数列表中,所以此特性不适用于特点。

string FirstName! { get; set; } // ERROR
不能用于 out / ref / in 的参数

public void M(out string x!) {} // ERROR

参阅
[Proposal: Simplified Null Argument Checking]
[Unit test: NullCheckedParameterTests.cs]
[LDM-2019-07-10.md]

原文地址https://www.cnblogs.com/Rwing/p/csharp-9-0-preview-null-arg-checking.html