C# 几个特殊运算符的理解和Nullable<T> 的研究
可空值类型和?运算符
谈到运算符,大家一定很熟悉,但是对所有的运算符都能掌握吗? 看了下面代码再回答。
Nullable<Int32> count = ;
int? i = ;
bool? flag = false;
bool hasValue = flag ?? false;
相信在大多数情况下,对第三行和第7行的使用方法比较少。他们究竟代表啥含义,int? 和 int 有什么区别, “??”运算符是什么意思?
这个问题就需要提到C#中可空值类型(Nullable),顾名思义,他就是一个可以为null的值类型,嗯,是为null的值类型,没听错。不是值类型不能为空,为啥要引入一个可为空的值类型呢?这就需要涉及到实际开发中碰到的问题来看。例如,设计一个数据库时,开奖一个列的数据类型定义为32位整数,并且可以映射到FCL的Int32。但是有些情况下,数据库列为空,这样从数据库读出来的数据在映射为FCL的数据类型时该怎么办?CLR中不能讲一个Int32表示成null。
这样引入可空值类型就是有必要的.上面代码中第一行就是可空值类型的使用,他是一个泛型类
public struct Nullable<T> where T : struct { }
T 被限定为struct,即值类型,如果是引用类型就没必要使用可空值类型,可以直接赋值为null。那么第三行的代码是怎么回事呢? 这就是用"?"来表示的可空值类型,Nullable<Int32> 等同于 Int32? ,个人观点来说Nullable<T>这种写法更具有直观性。
从上面看出可控制类型是个类,因此Nullable<Int32>和Int32 是不能直接来用=赋值的(编译器报错),那么他们在使用过程中就进行类型转换,例如
int x = ;
int? a = x; //正确
int? z = (int?)x;//正确
//int y = a; //Error Cannot implicitly convert type 'int?' to 'int'
int y = (int)a;//正确
第二行代码中赋值是进行了隐式类型转换,编译器没有报错,第三行进行显式类型转换也没有问题。但是第四行就会报错,需要强制类型转换。那么有类型转换,那么肯定会联想到装箱和拆箱,那么编译器是怎么装箱和拆箱的呢?
装箱:当CLR对一个Nullable<T>实例进行装箱时,首先检查他是否为null,如果是,CRL不进行任何操作,直接返回null。如果实例不为null,CLR对可空值实例中的值进行装箱 。
Int32? n = null;
object o = n;
拆箱:可以将一个已装箱的值类型T拆箱成一个T或者一个Nullable<T>, 如果已装箱的值类型引用为null,就拆箱成一个Nullable<T>,
object obj1 = null;
object obj2 = ;
int? o1 = (int?)obj1;
int? o2 = (int?)obj2;
int i1 = (int)obj1;//NullException
int i2 = (int)obj2;
Nullable<T>的类型
下面我们来看一下Nullable<T>的类型,可以使用代码查看,
Nullable<Int32> count = ;
Console.WriteLine(count.GetType());//"System.Int32"
为什么Nullable<Int32>的类型和Int32的类型相同呢?如果他们真的相同,为什么不能直接赋值,要进行强制转换呢?这就是CLR对我们撒谎了。
??运算符
最后我们了解一下运算符“??”(null-coalescing operator 空接合运算符),他是一个类似于?:运算符的的运算符,a??b 表示如果a 不等于null,则返回a, 否则返回b。对于使用不使用,什么时候使用 仁者见仁智者见智,所以不多说,只给出一个例子。
Int32? temp = null;
Int32 temp1 = temp ?? ; //Equals temp1 = temp.HasValue ? temp.Value:123;
C# 几个特殊运算符的理解和Nullable<T> 的研究的更多相关文章
- c语言 &取地址运算符的理解
对于c语言中的&运算符,百度百科是这样定义的:(&p)则是这样一种运算,返回当时声明p 时开辟的地址:但是根据我对代码的观察,我觉得&运算符不只是返回地址的功能: 例如: in ...
- JS按位非(~)运算符与~~运算符的理解分析
按位非运算符,简单的理解就是改变运算数的符号并减去1,当然,这是只是简单的理解能转换成number类型的数据. 那么,对于typeof var!==”number”的类型来说,进行运算时,会尝试转化成 ...
- js中得~~是什么意思/JS按位非(~)运算符与~~运算符的理解分析
其实是一种利用符号进行的类型转换,转换成数字类型 ~~true == 1 ~~false == 0 ~~"" == 0 ~~[] == 0 ~~undefined ==0 ~~!u ...
- Java中移位操作运算符的理解
java中的移位运算符有三种: 1. <<: 左移 2. >>: 右移 3. >>>: 无符号右移 使用方法:左移就是将左边的操作数在内存中的二进制数据左移指 ...
- php中&运算符的理解与使用
php的引用(就是在变量或者函数.对象等前面加上&符号) 在PHP 中引用的意思是:不同的名字访问同一个变量内容. 变量的引用 PHP 的引用允许你用两个变量来指向同一个内容 例一: < ...
- C语言中关于逗号运算符的理解
在C语言中运算符有很多,包括算数运算符.关系运算符.赋值运算符.位运算符.逻辑运算符.三目运算符.sizeof运算符.逗号运算符等等,那今天我们就重点来给大家讨论一下关于逗号运算符的一些运算规则. 首 ...
- Java 位运算符 深入理解
在Java中存在着这样一类操作符,是针对二进制进行操作的.它们各自是&.|.^.~.>>.<<.>>>几个位操作符.不管是初始值是依照何种进制,都会换 ...
- 短路运算符&&、或运算符||的理解
一.短路运算符&& 1.当只有两个表达式的时候(如a&&b),先看第一个表达式转换成布尔值的结果若为真,那么再看第二个表达式转换成布尔值的结果,就可以返回该表达式的值了 ...
- memcache 线程深入理解分析 及 源码研究
http://blog.csdn.net/huithe/article/details/8006186
随机推荐
- CodeForces 685B Kay and Snowflake
树的重心,树形$dp$. 记录以$x$为$root$的子树的节点个数为$sz[x]$,重儿子为$son[x]$,重心为$ans[x]$. 首先要知道一个结论:以$x$为$root$的子树的重心$ans ...
- openwrt 添加 应用(luci-application)
openwrt 添加应用的几个步骤如下: (1)在目录 ./feeds/luci/applications 下添加要增加的应用,譬如 "luci-test" (2)里面应该包含以下 ...
- iosAPP打包上架xcode中Archive提交成功以后,不提示构建版本问题
最近在项目更新时遇到Archive提交到开发者中心成功后,一直不提示构建版本信息,可能导致的原因是由于ios10以后对于APP中调用手机相册或摄像头麦克风时需要配置plist文件,配置如下内容或许会解 ...
- sim808模块收发送短信
一,简介 SIM 808发送短信分text模式和PDU模式.text模式已ascii码发送短信,这种模式比较简单,发送命令AT+CMGF=1就可以发送短信,而PDU模式比较复杂,首先发送命令AT+CM ...
- js将xml对象,xml文件解析成xml dom对象,来对对象进行操作
由于ie与其他的浏览器对于xml文件的解析方式不同,所以有不同的解析方式 1.1 IE解析xml文件的方式 var xmlDoc=new ActiveXObject("Microsoft.X ...
- java导出数据Excel总结
//创建获取到JFileChooser的文件名的JTextField public JTextField getTextField(Container c){ JTextField textField ...
- Redis字符串类型相关操作命令
string是redis最基本的类型,可以包括任何类型数据,如jpg图片或者序列化对象. 单个value最大上限是1G字节 如果只使用string类型,redis就可以被看做具有持久化特性的memca ...
- Ubuntu操作相关笔记
Eclipse添加图标 #sudo vim /usr/share/applications/eclipse.desktop 写入以下内容 [Desktop Entry] Name=Eclipse Co ...
- SQL语句的优化
1.创建索引 表中数据经常需要用的哪些字段数据进行过滤,则添加该字段的索引,索引相当如一本书的目录,能加快查询数据的速度:同时在新建索引的时候,将需要查询的列,在包含性 列中新增上去,能减少查询语句的 ...
- String.IsNullOrEmpty()和String.IsNullOrWhiteSpace()的区别
string.IsNullOrEmpty 这个是判断字符串是否为:null或者string.Empty或者“”,但不包含空格 .如果是如"\t"或者“ ” 这样的字符就返回fa ...