首页 文章详情

C# 11 移除了一个新特性

DotNet NB | 108 2022-04-27 18:48 0 0 0
UniSMS (合一短信)

在先前的 C# 11 预览版本中,C# 11 引入了一个新特性,允许在参数名称的末尾加上 !! 来简化空值检查(null-checking)。

比如下面这个方法使用传统的方式进行参数空值检查:

public static void M(string s)
{
if (s is null)
{
throw new ArgumentNullException(nameof(s));
}
// Body of the method
}

使用 !! 语法可以简写为:

public static void M(string s!!)
{
// Body of the method
}

此简写和上面的 if (param is null) throw new ArgumentNullException(...) 是等效的。

但此特性的预览版出来后,引起了社区的很多争论和反馈(来自于 GitHub 评论、MVP、社交媒体、会议听众等)。反对的观点归纳一下,主要有如下两种:

  1. 引入 !! 语法的同时也牺牲了可读性。在大多数语言中单个 ! 符号表示取反,数学中表示阶乘,而用 !! 表示“不能为空”就显得有些奇怪。与其引入 !!,不如引入一个新的 notnull 关键字。

  2. 不管是引入 !! 还是 notnull 作为空值检查,都会与 NRT (Nullable Reference Types) 产生冲突,因为在 NRT 中本身就可以添加严格的空值检查。

微软 C# 团队表示感谢所有的反馈,社区的反馈使团队的洞察更广泛,将重新考虑是否在 C# 11 中引入这个新特性。但由于团队没有足够的信心认为这个特性是 C# 正确的功能设计,因此决定将其从 C# 11 中删除,在将来的版本中可能还会继续探讨这个话题,引入更好的设计。

虽然移除了 !! 特性,但有好几种有效的方式可以用一行代码来进行空值检查。如果你使用的是 .NET 6,建议使用 ArgumentNullException.ThrowIfNull 方法:

public static void M(string myString)
{
ArgumentNullException.ThrowIfNull(myString);
// method
}

使用 ThrowIfNull 方法的好处之一是它使用 CallerArgumentExpression 来自动在异常消息中包含参数名称:

System.ArgumentNullException: 'Value cannot be null. (Parameter 'myString')'

附:关于移除 !! 特性的官方博文:

https://devblogs.microsoft.com/dotnet/csharp-11-preview-updates/


推荐阅读:
【译】.NET 7 预览版 1 中的 ASP.NET Core 更新
【译】C# 11 特性的早期预览
【译】在 ASP.NET 和 ASP.NET Core 之间共享代码
【译】ASP.NET Core 6 中的性能改进
【译】.NET 6 网络改进

点击下方卡片关注DotNet NB

一起交流学习

▲ 点击上方卡片关注DotNet NB,一起交流学习

请在公众号后台

回复 【路线图】获取.NET 2021开发者路线图
回复 【原创内容】获取公众号原创内容
回复 【峰会视频】获取.NET Conf开发者大会视频
回复 【个人简介】获取作者个人简介
回复 【年终总结】获取作者年终总结
回复 加群加入DotNet NB 交流学习群

长按识别下方二维码,或点击阅读原文。和我一起,交流学习,分享心得。


good-icon 0
favorite-icon 0
收藏
回复数量: 0
    暂无评论~~
    Ctrl+Enter