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

🚩可空类型

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

值类型不可为null,如下图所示:C#中的可空类型以及??、?.运算符

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

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

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

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

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

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

 if (a == null
 {
     //SomeCode
 }

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

if(a.HasValue) 

    //SomeCode
}

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

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

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

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

 int? a;

int?就是System.Nullable<int>的缩写。

看到这里,可能很多朋友和我有一样的疑问,好像可空类型的存在就是为了让值类型可以为空,但是在平时经常看到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);
        }

运行结果如下所示:

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

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

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

运行结果如下所示:

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

第一个表达式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


原文始发于微信公众号(DotNet学习交流):C#中的可空类型以及??、?.运算符

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/230800.html

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!