使用int?来确保值类型也可以为null

继上一篇“你确认C#中TryParse比Parse好?动手测试才知道!”后,本文继续讲《编写高质量代码改善C#程序的157个建议》一书第5个建议“使用int?来确保值类型也可以为null”。喜欢本书请到各大商城购买原书,支持正版。

基元类型为什么需要为null?考虑两个场景:

  1. 数据库中一个int字段可以被设置为null。在C#中,值被取出来后,为了将它赋值给int类型,不得不首先判断一下它是否为null。如果将null直接赋值给int 类型,会引发异常。
  2. 在一个分布式系统中,服务器需要接收并解析来自于客户端的数据。一个int型数据可能在传输过程中丢失或被篡改了,转型失败后应该保存为null值,而不是提供一个初始值。

类似的场景还有很多,所以从.NET 2.0开始,FCL中提供了一个额外的类型:可以为空的类型Nullable。它是一个结构体,声明如下:

[SerializableAttribute]
public struct Nullable<T> where T : struct

因为是结构体,所以只有值引用类型才可以作为“可以为空的类型”(引用类型本身就可以为null)。一个可以为空的int类型表示为:

Nullableeint> i = null;

它也可以表示为:

int? i = null;

语法T?是 Nullable的简写,两者可以相互转换。可以为 null 的类型表示其基础值类型正常范围内的值再加上一个null值。例如,Nullable,其值的范围为—2147 483 648~2 147 483 647,再加上一个null值。

现在来看看可空类型和基元类型的互相转换。基元类型提供了其对应的可空类型的隐式转换,如下所示:

int? i = null;
int j = 0;
i = j;

反过来,可空类型不可隐式转换为对应的基元类型,正确的转换形式如下:

int? i = 123;
int j;
if (i.Hasvalue)
{
  j = i.value;
}
else
{
  j = 0;
)

但是,这段代码看上去是不是有点烦琐?所以,在阐述可空类型的时候,不得不提到??运算符。??最大的用处就是将可空类型的值赋值给对应的基元类型进行简化,上文代码的一个简化形式就是:

int? i = 123;
int j = i ?? 0;

int j = i ?? 0;表示的意思是,如果i的HasValue为 true,则将i的value赋值给j:否则,就给j赋值为0。

下一篇我们接着读《建议6:区别readonly和const的使用方法 》,欢迎关注微信公众号【小市民在西河】。

原文出处:微信公众号【小市民在西河】

原文链接:

本文观点不代表Dotnet9立场,转载请联系原作者。

发表评论

登录后才能评论

评论列表(1条)

  • 君一席
    君一席 2021年2月26日 11:19

    空合并运算符(??),是C#7.0中引入的语法糖,需要.Net Framework 4.6.2 支持。