详解C#中检查null的语法糖

目录
  • 函数参数null检查
    • 传统写法
    • ThrowIfNull
    • C# 11的!!语法(已经取消)
  • 有关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给我们准备了许多的语法糖,只能说非常简便了。有很多人会说这个可读性不好,或者觉得这是“茴字的几种写法”似的歪门邪道,我只能说,传统的语法也不是说取消了,语言有发展,只要还是比较审慎的,我觉得还是一件好事。

到此这篇关于详解C#中检查null的语法糖的文章就介绍到这了,更多相关C#检查null内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • C#6 null 条件运算符

    1. 老版本的代码 namespace csharp6 { internal class Person { public string Name { get; set; } } internal class Program { private static void Main() { Person person = null; string name = null; if (person != null) { name = person.Name; } } } } 在我们使用一个对象的属性的时候

  • C#的十种语法糖介绍

    目录 语法糖 一.自动属性 二.隐式类型(var) 三.参数默认值和命名参数 四.对象初始化器和集合初始化器 五.匿名类和匿名方法 匿名类型 匿名类型的嵌套 匿名类型的限制: 匿名方法 六.扩展方法 七.内置泛型委托 八.Lambda表达式 九.标准查询运算符 十.Linq 语法糖 指计算机语言中添加的某种语法,这种语法对语言的功能并没有影响,但是更方便程序员使用.通常来说使用语法糖能够增加程序的可读性,从而减少程序代码出错的机会. 需要声明的是“语法糖”这个词绝非贬义词,它可以给我们带来方便,

  • 浅谈C# 中的可空值类型 null

    C# 不允许把 null 赋给一个值类型的数据.在 C# 中,以下语句是非法的: 复制代码 代码如下: int a = null;    // 非法 但是,利用 C# 定义的一个修饰符,可将一个变量声明为一个可空(nullable)值类型.可空值类型在行为上与普通值类型相似,但可以将一个 null 值赋给它.如下所示: 复制代码 代码如下: int? a = null;      // 合法 当把一个变量定义为可空值类型时,该变量依然可以被赋值为 0,代码如下所示: 复制代码 代码如下: usi

  • C#检查foreach判读是否为null的方法

    本文运用图片给大家介绍了C#如何检查foreach判读其是否为null,我们下面话不多说,直接来看内容吧. 1.foreach遍历列表或数组时,如果list或数组为null,就会报错,如下图: 2.不知道微软封装foreach的为什么不先检查要遍历的对象是否为null,这样就导致,我们在写代码时,遍历列表时就要先判断列表是否为null,如下图: 3.为了简化这一判断是否null的过程,我写了一个扩展方法,因为列表和数组都继承IEnumerable接口,所以该扩展方法就扩展在IEnumerable

  • 详解C#中检查null的语法糖

    目录 函数参数null检查 传统写法 ThrowIfNull C# 11的!!语法(已经取消) 有关null的一些操作 ?? ??= ?. ?[] 一些操作 结语 今天看到已经更新了devblogs,新增的C# 11的!!(用于检查null的语法)经过非常长的讨论,最后取消了.然后我又想起来null检查,这个可以说一说. 函数参数null检查 传统写法 写一个函数的时候,最经典的检查,估计也是大家最常使用的null检查,应该是这样的吧: public static void GetV1(stri

  • 详解VUE中的插值( Interpolation)语法

    背景分析 在传统的html页面中我们可以定义变量吗?当然不可以,那我们假如希望通过变量的方式实现页面内容的数据操作也是不可以的.当然我们可以在服务端通过定义html标签库方式,然后以html作为模板,在服务端解析也可以实现,但这样必须通过服务端进行处理,才可以做到,能不能通过一种技术直接在客户端html页面中实现呢? VUE中的插值语法 这种语法是为了在html中添加变量,借助变量方式与js程序中的变量值进行同步,进而简化代码编写.其基本语法为: <HTML元素>{{变量或js表达式}}<

  • 详解Python3 中的字符串格式化语法

    一.旧式的字符串格式化 % 操作符 参考以下示例: >>> name = "Eric" >>> "Hello, %s." % name 'Hello, Eric.' 当有多个变量需要插入到字符串中时: >>> name = "Eric" >>> age = 74 >>> "Hello, %s. You are %s." % (name,

  • 详解es6超好用的语法糖Decorator

    Decorator(修饰器/装饰器)是es6提出的语法糖,用于修改类的行为.不过目前主流浏览器都没有很好的支持,我们需要用babel来转换为浏览器能识别的语言.在这篇文章中将介绍decorator的基础用法和一些应用实例. 1.修饰类 (1) 基础用法 @testable class MyClass{} function testable(target){ target.isTestable=true } console.log(MyClass.isTestable) // true 贴一下ba

  • 详解MySQL中的NULL值

    我们已经看到使用WHERE子句的SQL SELECT命令来从MySQL表获取数据.但是,当我们试图给的条件比较字段或列的值为NULL,它不能正常工作. 为了处理这种情况,MySQL提供了三大运算符 IS NULL: 此运算符返回true,当列的值是NULL. IS NOT NULL: 运算符返回true,当列的值不是NULL. <=> 操作符比较值(不同于=运算符)为ture,即使两个NULL值 涉及NULL条件是特殊的.不能使用 =NULL 或 !=NULL 寻找NULL值的列.这种比较总是

  • 详解PHP中的null合并运算符

    null合并运算符是一个好东西,有了它我们就能很方便的获取一个参数,并能在其为空的情况下提供一个默认值.比如在js中可以用||来搞: function setSomething(a){ a = a || 'some-default-value'; // ... } 而在PHP中,可惜PHP的||总是返回true或false,无法这样来搞.  PHP7才正式加入了??这个运算符: // 获取user参数的值(如果为空,则用'nobody') $username = $_GET['user'] ??

  • 详解shell中>/dev/null 2>&1到底是什么

    前言 相信大家经常能在shell脚本中发现>/dev/null 2>&1这样的语句.以前的我并没有去深入地理解这段命令的作用,照搬照用,直到上周我将这段命令不小心写成了2>&1 >/dev/null,出了一点小问题之后,我才开始去了解这段命令背后的"玄机". shell重定向介绍 就像我们平时写的程序一样,一段程序会处理外部的输入,然后将运算结果输出到指定的位置.在交互式的程序中,输入来自用户的键盘和鼠标,结果输出到用户的屏幕,甚至播放设备中.而

  • 详解java中String值为空字符串与null的判断方法

    Java空字符串与null的区别 1.类型 null表示的是一个对象的值,而不是一个字符串.例如声明一个对象的引用,String a=null. ""表示的是一个空字符串,也就是说它的长度为0.例如声明一个字符串String s="". 2.内存分配 String a=null:表示声明一个字符串对象的引用,但指向为null,也就是说还没有指向任何的内存空间. String s="":表示声明一个字符串类型的引用,其值为""空

  • 详解c++中的异常

    一.什么是异常处理 一句话:异常处理就是处理程序中的错误. 二.为什么需要异常处理,异常处理的基本思想 C++之父Bjarne Stroustrup在<The C++ Programming Language>中讲到:一个库的作者可以检测出发生了运行时错误,但一般不知道怎样去处理它们(因为和用户具体的应用有关):另一方面,库的用户知道怎样处理这些错误,但却无法检查它们何时发生(如果能检测,就可以再用户的代码里处理了,不用留给库去发现). Bjarne Stroustrup说:提供异常的基本目的

  • 详解Struts2中对未登录jsp页面实现拦截功能

    Struts2中拦截器大家都很经常使用,但是拦截器只能拦截action不能拦截jsp页面.这个时候就有点尴尬了,按道理来说没登录的用户只能看login界面不能够通过输入URL进行界面跳转,这显然是不合理的.这里介绍Struts2中Filter实现jsp页面拦截的功能.(有兴趣的人可以去研究Filter过滤器的其它用法,因为利用过滤器也可以实现action拦截的功能) 下面直接上代码,边看边分析实现步骤和原理. 1.web.xml中的配置信息: <filter> <filter-name&

随机推荐