C#中检查null的语法糖
今天看到已经更新了devblogs,新增的C# 11的!!(用于检查null的语法)经过非常长的讨论,最后取消了。然后我又想起来null检查,这个可以说一说。
函数参数null检查
传统写法
写一个函数的时候,最经典的检查,估计也是大家最常使用的null检查,应该是这样的吧:
public static void GetV1(string prompt)
{
if (prompt is null) throw new ArgumentNullException(nameof(prompt));
Console.WriteLine(prompt);
}
ThrowIfNull
这个写起来也没啥问题,但是总觉得有点不舒适。.NET 6在ArgumentNullException中新增了ThrowIfNull方法,可以写的更优雅一点。
public static void GetV2(string prompt)
{
ArgumentNullException.ThrowIfNull(prompt);
Console.WriteLine(prompt);
}
异常的时候,就会出现:System.ArgumentNullException: 'Value cannot be null. (Parameter 'prompt')'。这个是不是简单了点?可是还是需要写一行。
C# 11的!!语法(已经取消)
C# 11刚preview的时候,我就瞄到了这个特性,现在依然可以通过设置preview来进行启用,但是以后正式发布估计就不行了。
它通过在参数后面叠加!!表示此参数不可为空,运行时会自动进行检查,如果是null就直接弹出错误。
public static void GetV3(string prompt!!)
{
Console.WriteLine(prompt);
}
这个代码会被编译器翻译成:
public static void GetV3(string prompt!!)
{
if (prompt is null) {
throw new ArgumentNullException(nameof(prompt));
}
Console.WriteLine(prompt);
}
这样大家就可以专注于业务代码,不需要经常考虑异常检查了。至于为什么这个东西最后还是被删除了,可以从讨论中看到一丝端倪,首先是感觉非常纠结于这个语法,两个叹号;然后就是已经有比较多的方式可以实现检查了,这个东西是否有必要。反正最终是以后再讨论了,不过也可以看出来C#语言工作组对语言的特性讨论非常谨慎。
他们还讨论了很多别的形式,每种都提出了各自的优缺点挺有意思的,能看出来有一点设计语言的严谨和小强迫症在,点赞~
void M(string s!!);
void M(string! s);
void M(string s!);
void M(notnull string s);
void M(string s ?? throw);
void M(string s is not null);
void M(checked string s);
void M(string s) where s is not null;
有关null的一些操作
说起这个,就顺便说说c#处理null的另外几个语法糖吧。
??
如果左边是的null,那么返回右边的操作数,否则就返回左边的操作数,这个在给变量赋予默认值非常好用。
int? a = null;
int b = a ?? -1;
Console.WriteLine(b); // output: -1
??=
当左边是null,那么就对左边的变量赋值成右边的
int? a = null;
a ??= -1;
Console.WriteLine(a); // output: -1
?.
当左边是null,那么不执行后面的操作,直接返回空,否则就返回实际操作的值。
using System;
public class C {
public static void Main() {
string i = null;
int? length = i?.Length;
Console.WriteLine(length ?? -1); //output: -1
}
}
?[]
索引器操作,和上面的操作类似
using System;
public class C {
public static void Main() {
string[] i = null;
string result = i?[1];
Console.WriteLine(result ?? "null"); // output:null
}
}
注意,如果链式使用的过程中,只要前面运算中有一个是null,那么将直接返回null结果,不会继续计算。下面两个操作会有不同的结果。
using System;
public class C {
public static void Main() {
string[] i = null;
Console.WriteLine(i?[1]?.Substring(0).Length); //不弹错误
Console.WriteLine((i?[1]?.Substring(0)).Length) // System.NullReferenceException: Object reference not set to an instance of an object.
}
}
一些操作
//参数给予默认值
if(x == null) x = "str";
//替换
x ??= "str";
//条件判断
string x;
if(i<3)
x = y;
else
{
if(z != null) x = z;
else z = "notnull";
}
//替换
var x = i < 3 ? y : z ?? "notnull"
//防止对象为null的时候,依然执行代码
if(obj != null)
obj.Act();
//替换
obj?.Act();
//Dictionary取值与赋值
string result;
if(dict.ContainKey(key))
{
if(dict[key] == null) result = "有结果为null";
else result = dict[key];
}
else
result = "无结果为null";
//替换
var result= dict.TryGetValue(key, out var value) ? value ?? "有结果为null" : "无结果为null";
结语
原来新定的C# 11提供了一个新的??,话说我个人还是挺喜欢这个特性的,不管以什么形式出现吧,期待以后再见。
C#中为了处理null给我们准备了许多的语法糖,只能说非常简便了。有很多人会说这个可读性不好,或者觉得这是“茴字的几种写法”似的歪门邪道,我只能说,传统的语法也不是说取消了,语言有发展,只要还是比较审慎的,我觉得还是一件好事。
参考资料
- https://docs.microsoft.com/zh-cn/dotnet/csharp/language-reference/operators/member-access-operators#null-conditional-operators--and-
- https://docs.microsoft.com/zh-cn/dotnet/csharp/language-reference/operators/null-coalescing-operator
后记
一定要夸一下博客园,写完这篇文章想登陆博客园发布的时候,被登陆卡住了。弹出来和google一样的验证画面,找红绿灯找人行横道什么的,只能说我找了几分钟也没找明白,我确信我已经点的正确了,所有的区块,占上了有一点算不算?不知道也没有反馈,就点呀点呀,密码我已经按照要求设置的够复杂了,还有必要通过这种反人类的东西来验证吗?不理解,京东阿里之类的购物网站的验证也就拖一下完事,这博客园的后台估计比那些个地方还要敏感吧,赞一个!太赞了!
C#中检查null的语法糖的更多相关文章
- Java中的10颗语法糖
语法糖(Syntactic Sugar):也称糖衣语法,指在计算机语言中添加的某种语法,这种语法对语言的功能没有影响,但是更方便程序员使用.通常来说,使用语法糖能够增加程序的可读性,减少程序代码出错的 ...
- python中装饰器(语法糖)概念
“”“” 什么是装饰器? """ 还是通过一个例子来慢慢说明 先看下面的例子 def func_1(x): return x*2 def fun_2(x): return ...
- JVM(二):Java中的语法糖
JVM(二):Java中的语法糖 上文讲到在语义分析中会对Java中的语法糖进行解糖操作,因此本文就主要讲述一下Java中有哪些语法糖,每个语法糖在解糖过后的原始代码,以及这些语法糖背后的逻辑. 语法 ...
- Java 中的语法糖,真甜。
我把自己以往的文章汇总成为了 Github ,欢迎各位大佬 star https://github.com/crisxuan/bestJavaer 我们在日常开发中经常会使用到诸如泛型.自动拆箱和装箱 ...
- Hollis原创|不了解这12个语法糖,别说你会Java
GitHub 2.5k Star 的Java工程师成神之路 ,不来了解一下吗? GitHub 2.5k Star 的Java工程师成神之路 ,真的不来了解一下吗? GitHub 2.5k Star 的 ...
- Java的12个语法糖【转】
本文转载自公众号 Hollis 原创: 会反编译的 Hollis 侵权删 本文从 Java 编译原理角度,深入字节码及 class 文件,抽丝剥茧,了解 Java 中的语法糖原理及用法,帮助大家在学 ...
- Java语法糖详解
语法糖 语法糖(Syntactic Sugar),也称糖衣语法,是由英国计算机学家 Peter.J.Landin 发明的一个术语,指在计算机语言中添加的某种语法,这种语法对语言的功能并没有影响,但是更 ...
- 转:【深入Java虚拟机】之六:Java语法糖
转载请注明出处:http://blog.csdn.net/ns_code/article/details/18011009 语法糖(Syntactic Sugar),也称糖衣语法,是由英国计算机学家P ...
- 深入理解 Java try-with-resource 语法糖
背景 众所周知,所有被打开的系统资源,比如流.文件或者Socket连接等,都需要被开发者手动关闭,否则随着程序的不断运行,资源泄露将会累积成重大的生产事故. 在Java的江湖中,存在着一种名为fina ...
随机推荐
- 数据结构 - 顺序表 C++ 实现
顺序表 此处实现的顺序表为**第一个位置为 data[0] **的顺序表 顺序表的定义为 const int MAX = 50; typedef int ElemType; typedef struc ...
- JDK8新特性关于Stream流
在Java1.8之前还没有stream流式算法的时候,我们要是在一个放有多个User对象的list集合中,将每个User对象的主键ID取出,组合成一个新的集合,首先想到的肯定是遍历,如下: 1 2 3 ...
- SpringCloud项目中接入Nacos作为注册中心
具体demo https://blog.csdn.net/qq_33619378/article/details/95212754 <?xml version="1.0 ...
- 利用 ps 怎么显示所有的进程? 怎么利用 ps 查看指定进程的信息?
ps -ef (system v 输出)ps -aux bsd 格式输出ps -ef | grep pid
- 什么是 YAML?
YAML 是一种人类可读的数据序列化语言.它通常用于配置文件. 与属性文件相比,如果我们想要在配置文件中添加复杂的属性,YAML 文件就更加 结构化,而且更少混淆.可以看出 YAML 具有分层配置数据 ...
- Redis的数据类型操作(二)
1.String:key-value(做缓存) Redis中所有的数据都是字符串.命令不区分大小写,key是区分大小写的.Redis是单线程的.Redis中不适合保存内容大的数据. get.set.i ...
- 设计一个简单的devops系统
前言 公司设计的RDMS挺好用的,我也照猫画虎简单的设计一个DevOps系统,与大家分享,不足之处欢迎拍砖,以免误人子弟 前置条件 gitlab gitlab-runner k8s 1. gitlab ...
- SVN在idea中操作解析图
进入的位置
- 视觉SLAM十四讲:从理论到实践 两版 PDF和源码
视觉SLAM十四讲:从理论到实践 第一版电子版PDF 链接:https://pan.baidu.com/s/1SuuSpavo_fj7xqTYtgHBfw提取码:lr4t 源码github链接:htt ...
- 前馈控制+PID
参考来源: 北京交通大学 硕士学位论文 基于脉冲串控制的含位置反馈和前馈补偿的位置控制算法的研究 赵旺升