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

网友投稿 380 2022-06-22


前言

随着 .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 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]


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:C# Log4Net学习笔记:记录日志到数据库(cp是什么意思?)
下一篇:C#实现FTP上传资料(乘风破浪的姐姐第三季)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~