C#中的可空类型以及??、?.运算符

可空类型

值类型必须包含一个值,它们可以在声明之后、赋值之前,在未赋值的状态下存在,但不能使用未赋值的变量,而引用类型可以是null。

值类型不可为null,如下图所示:

在这里插入图片描述

引用类型可以为null,如下图所示:

在这里插入图片描述

有时让值类型为空是很有用的,泛型使用了System.Nullable类型提供了使值类型为空的一种方式。

这样即使给值类型赋值null,编译器也不会报错,如下图所示:

在这里插入图片描述

现在可以像测试引用类型一样测试可空类型,看看它们是否为null,如下所示:

 if (a == null) 
 {
     //SomeCode
 }

另外还可以使用HasValue属性,如下所示:

if(a.HasValue) 
{ 
    //SomeCode
}

但是这不适用于引用类型,即使引用类型有一个HasValue属性,也不能使用这种方法,因为引用类型的变量值为null,就表示不存在对象,当然就不能通过对象来访问这个属性,否则会抛出一个异常。

可使用Value属性查看可空类型的值。如果HasValue为true,就说明Value属性有一个非空值。但如果HasValue是false,就说明变量被赋予了null,访问Value属性会抛出异常,如下所示:

在这里插入图片描述

可空类型非常有用,C#也为我们提供了关于可空类型的语法糖,声明一个可空类型,也可以使用如下的语法:

 int? a;

int?就是System.Nullable的缩写。

看到这里,可能很多朋友和我有一样的疑问,好像可空类型的存在就是为了让值类型可以为空,但是在平时经常看到string?的用法,string不是一个引用类型吗?不是本身就可以为null吗?

在网上搜索之后,我才知道在C#中,string 类型虽然被设计为引用类型,但它表现得像值类型。实际上,string 类型的对象在内存中是以引用的形式存储的,但由于它是不可变的(immutable),在许多方面表现得像值类型。

当你对一个字符串进行操作时,实际上是创建了一个新的字符串对象,而原始字符串对象保持不变。这种不可变性使得字符串的操作更安全,同时也更容易进行优化。

需要注意的是,C#中的其他值类型(如intdouble等)是直接存储其值而不是引用,而string是一个例外,被设计为引用类型。

??运算符

??运算符被称为空接合运算符(null coalescing operator),是一个二元运算符,允许给可能等于null的表达式提供另一个值。如果第一个操作数不是null,该运算符就等于第一个操作数,否则,该运算符就等于第二个操作数。

下面的两个表达式的作用是相同的:

a ?? b
a == null ? a : b

可以使用??运算符为可空类型为null时,提供其他一个值,如下所示:

static void Main(string[] args)
        {
            int? a = null;
            int result = a * 2 ?? 6;
            Console.WriteLine(result);
        }

运行结果如下所示:

在这里插入图片描述

因为a为null,a*2也为null,所以等于第二个表达式,如果第一个表达式不为null,则为第一个表达式的值,如下所示:

 static void Main(string[] args)
        {
            int? a = 2;
            int result = a * 2 ?? 6;
            Console.WriteLine(result);
        }

运行结果如下所示:

在这里插入图片描述

第一个表达式a*2=4不为null,则结果为第一个表达式的值,即结果等于4。

?.运算符

?.运算符通常称为空条件运算符,有助于避免繁杂的空值检查造成的代码歧义。

比如,想要得到给定客户的订单数,就需要在设置计数之前检查空值,如下所示:

int count = 0;
if(customer.orders != null)
{
    count = customer.orders.Count();
}

因为如果只编写

int count = customer.orders.Count();

那么当没有订单时(即为null)时,就会抛出System.ArgumentNullException异常。

使用?.运算符,会把int? count设置为null,而不是抛出一个异常。

int? count = customer.orders?.Count();

结合??运算符和?.运算符,就可以在结果为null时设置一个默认值。

int? count = customer.orders?.Count() ?? 0;

参考

《C#入门经典(第7版)》——Benjamin Perkins、Jacob Vibe Hammer、Jon D. Reid


如果你也对C#感兴趣,欢迎关注微信公众号,DotNet学习交流,一起成长进步~
在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值