C#2.0之可空类型
可空类型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>的代码了,HasValue是bool默认是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;
意思就是i为null吗?不为null就用i的值返回,为null就用后面的值返回,而且这样条件可以一直延续下去。空合并操作符还可以适用于引用类型
Var x= i??y??d??c??0;
我们还可以空合并操作符来简化我们的逻辑判断,重写比較器CompareTo,让其返回不是int而是int?。这样我们就可以使用??了
C#2.0之可空类型的更多相关文章
- 四、可空类型Nullable<T>到底是什么鬼
值类型为什么不可以为空 首先我们都知道引用类型默认值都是null,而值类型的默认值都有非null. 为什么引用类型可以为空?因为引用类型变量都是保存一个对象的地址引用(就像一个url对应一个页面),而 ...
- 【C#】可空类型(Nullable)
C# 可空类型(Nullable) C# 提供了一个特殊的数据类型,nullable 类型(可空类型),可空类型可以表示其基础值类型正常范围内的值,再加上一个 null 值. 例如,Nullable& ...
- swift_枚举 | 可为空类型 | 枚举关联值 | 枚举递归 | 树的概念
***************可为空的类型 var demo2 :we_demo = nil 上面这个代码串的语法是错的 为什么呢, 在Swift中,所有的类型定义出来的属性的默认值都不可以是nil ...
- Guava-Optional可空类型
接上篇Guava之Joiner和Splitter,本篇将介绍Guava的另外一个有用的对象Optional,这在Java中Google Guava首先给我们提出可空对象模型的.在其他语言如c#这是已经 ...
- [C#] 可空类型的实现原理
int? 是可为null的值类型.只比int多一个值就是null. 思考: 同样的内存空间,怎么实现的多一个值的?都是4字节,32位,int?靠什么存在一个null值的. 发现: 分析一下内存,看看如 ...
- C#基础知识系列二(值类型和引用类型、可空类型、堆和栈、装箱和拆箱)
前言 之前对几个没什么理解,只是简单的用过可空类型,也是知道怎么用,至于为什么,还真不太清楚,通过整理本文章学到了很多知识,也许对于以后的各种代码优化都有好处. 本文的重点就是:值类型直接存储其值,引 ...
- C#学习笔记(六):可空类型、匿名方法和迭代器
可空类型 为啥要引入可空类型? 在数据库中,字段是可以为null值的,那么在C#中为了方便的操作数据库的值,微软引入了可空类型. 声明可空类型 我们可以使用两种方法声明一个可空类型: Nullable ...
- C# Nullable可空类型
一个Nullable类型就是基本类型加上一个"是否为null指示器"的合成类型.对于一个类型,如果既可以给他分配一个值,也可以给它分配null引用,我们就说这个类型是可空的. 可空 ...
- Kotlin——从无到有系列教程(5): 你该知道的Kotlin可空类型、空安全(null)、类型转换等特性
在我们熟知的Java中,定义一个变量可以默认不赋值,因为Java的系统会给我们默认赋一个默认值,并且Java可定义一个赋值为null的变量,这样在使用这个变量的时候都会去显示判断该变量是否为null. ...
随机推荐
- 把网站打包快速在线生成ios app的正确方法
下方的内容不用看了,请点这里 !点这里!IOS APP自助生成系统已上线,请马上去了解下: http://www.tao-jiujiu.com/post/188.html ============= ...
- Javascript 标识符及同名标识符的优先级
一.定义 标识符(Identifier)就是一个名字,用来对变量.函数.属性.参数进行命名,或者用做某些循环语句中的跳转位置的标记. //变量 var Identifier = 123; //属性 ( ...
- redis + cookies 实现持久登入
通过登入把用户信息和token加载到redis中去, 将token和部分用户信息存储在cookie中, 下次登入时 判断cookie的token在redis中是否存在, 存在就把用户信息加载出来自动登 ...
- Gradle 学习一
参考教程:https://guides.gradle.org/consuming-jvm-libraries/ 安装Gradle 下载地址:https://guides.gradle.org 配置环境 ...
- Katalon Studio之接口测试中token处理
前言 最近抽时间接触了一下Katalon Studio(后面简称KS),并且利用KS做了一些接口测试的试验,感觉还不错,不过其中接口授权中缺少通过token动态验证的方案,虽然KS支持Authoriz ...
- scala 下 sigmoid 与breeze.numeric.sigmoid差异对比
scala> val beforeInit = System.nanoTime;val handsgn = rd.map(x => 1.0 / (1.0 + Math.exp(-x))); ...
- c# 通过MailHelper发送QQ邮件
发送的方法 appsetting内容 第一个是发送邮件qq账号,第二个是QQ邮箱的POP3/SMTP服务码(下面会说怎么获取),第三个是服务器,第四个是端口 获取QQ邮箱的POP3/SMTP服务码 1 ...
- hibernate的session的增删查改
一.增 //******************增加****************** Customer c = new Customer(); c.setCust_name("阿里云&q ...
- 查询结果集转换成HTML存储过程
工作中经常需要用SQLServer发送报警或者业务报表邮件,每次现拼串也不是办法,故写了一个TableResult to HTML的存储过程 USE master; GO -- Description ...
- 【安富莱】【RL-TCPnet网络教程】第7章 RL-TCPnet网络协议栈移植(裸机)
第7章 RL-TCPnet网络协议栈移植(裸机) 本章教程为大家讲解RL-TCPnet网络协议栈的裸机移植方式,学习了上个章节讲解的底层驱动接口函数之后,移植就比较容易了,主要是添加库文 ...