首页 > 代码库 > 可空类型

可空类型

可空类型Nullable<T>

C#2.0之前 ,值类型一直不可以为null,但是实际开发中常常会有这样的需求,比如结束时间。

   

为什么不可以为null

对于引用类型来说,null代表着空引用。就像href中的javaScirpt:,在内存中这一区域会全部用零表示,在GC的时候也会更加的轻松,对于值类型来说零是一个有效值 。

当然也有相应的替代方式

魔值

犧牲一个我们似乎永远也用不到的值 ,比如maxValue。但是这样做是非常的不优雅的

使用标志位

一个值类型对应着一个bool的变量,false表示没有值,true表示有值 。这看起来还不错,但是要维护两份变量

使用引用类型

object是所有类型的基类,同时它也是引用类型。但是这样会有着反復的拆箱与装箱,这也并不是我们所想要的

   

C#2.0使用了Nullable<T>

这种解決方式非常的优美,Nullable<T>是一个泛型的结构体。首先限制了T必须为struct类型。

这样问题又来了,Nullable也是值类型,为什么会可以为null呢。其实这只是C#玩的一个小花招而已,下面我来写一个简易版本的MyNullable<T>

可以看下面MyNullable<T>的代码了,HasValuebool默认是false。如果通过構造函數斌值那么就是true了。

技术分享

下面是測試用例,x获取value会报异常nullable Object mush have a value,而y则不会。

技术分享

   

C#中我们甚至可以直接为Nullable<T>賦值为null,这就是編譯器和CLR做的小花招了,如果反編譯就会看到它的真实面貌。而之后的版本里,又增加了各种各样的語法糖,比如与null进行对比(重写了Equals方法)以及使用int?这样更直观的方式进行声明

   

比较的问题

一个nullInt与nullInt进行比较时,>=竟然永远是false。毕竟 null 也 应该等于null 嘛。。不过这个对于实际应用中不会造成任何问题

技术分享

   

   

as转换的性能缺陷

C#2.0中有了as转换操作符,在之前我们需要先is 是否是某类型然后再强制转换。而as一次就够了,但是令人惊讶的是它的性能竟然不如之前的解决方案,事实上是差很多,下次进行了测试两个版本

技术分享

   

技术分享

   

耗时分别是 1724 与 4919,不过我们敲码时如果整体性能不错,那么也可以使用as,毕竟优雅了很多。而且这也是一千万次的测试的结果

   

空合并操作符

对于可空类型的值类型,我们在判断时相比较值类型又多了一项判断那就是为null的判断。我们的代码看起来就是下面这样

If(i==null)

{

return 0;

}else

{

return I;

}

而空合并操作符??为我们提供了简便

Var x = i??0;
意思就是inull吗?不为null就用i的值返回,为null就用后面的值返回,而且这样条件可以一直延续下去。空合并操作符还可以适用于引用类型

Var x= i??y??d??c??0;

我们还可以空合并操作符来简化我们的逻辑判断,重写比較器CompareTo,让其返回不是int而是int?。这样我们就可以使用??

  

  

可空类型