首页 > 编程语言 >C#中检查null的语法糖

C#中检查null的语法糖

时间:2023-01-31 16:45:15浏览次数:36  
标签:prompt string C# void 语法 Console null public

 

今天看到已经更新了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给我们准备了许多的语法糖,只能说非常简便了。有很多人会说这个可读性不好,或者觉得这是“茴字的几种写法”似的歪门邪道,我只能说,传统的语法也不是说取消了,语言有发展,只要还是比较审慎的,我觉得还是一件好事。

标签:prompt,string,C#,void,语法,Console,null,public
From: https://www.cnblogs.com/zongcheng86/p/17079711.html

相关文章

  • 常用的CSS效果(1)
    单行省略overflow:hidden;text-overflow:ellipsis;white-space:nowrap;多行省略display:-webkit-box;overflow:hidden;......
  • pip安装psycopg2报错Could not find a version that satisfies the requirement psyco
    pip安装psycopg2报错在使用命令(pipinstallpsycopg2)安装psycopg2时,会报错:ERROR:Couldnotfindaversionthatsatisfiestherequirementpsycopg2(fromversions:......
  • 易灵思MIPI CSI 自环调试步骤
    转载自:易灵思MIPICSI自环调试步骤(qq.com)最近在帮助客户分析MIPI的问题,所以有此总结。第一次使用MIPI的人可能不知道怎么在易灵思平台上下手,今天我们来分享下MIPI的......
  • CF98E Help Shrek and Donkey
    linkSolutionbunnny之前搬的题,但是没有做......
  • strcmp函数
    原型:int strcmp(const char *s1, const char *s2);头文件:#include <string.h> 功能:用来比较两个字符串 参数:s1、s2为两个进行比较的字符串 返回值:若s1、s......
  • office二次开发设置页眉页脚
    _Application app;app.CreateDispatch(_T("Word.Application"));app.SetVisible(TRUE);//通过WORD宏可以知道,由于要使用Documents,于是我们定义一个并从app中取得Docum......
  • 5. RGCA架构设计过程
    介绍RGCA:RequirementGoalConceptArchitecture需求目标概念架构利益相关者与需求系统因为使人受益而存在;系统的主要需求也来源于利益相关方通过系统为一些......
  • 基于EasyCVR与AI技术的智慧园区视频大数据综合监管方案
    一、智慧园区背景园区面积范围广、人流量大、日常管理难度高,如何保障园区的安全生产已经成为当前的迫切要求,需要技术先进、稳定可靠的智慧安全系统来保障其正常运行、安全生......
  • Java并发——ThreadLocal详解
    引言ThreadLocal的官方API解释为:“该类提供了线程局部(thread-local)变量。这些变量不同于它们的普通对应物,因为访问某个变量(通过其get或set方法)的每个线程都有自己......
  • Docker的基本概念
    Docker的基本概念......