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
 
随机推荐
- DateTime & UTC 相互转化
			
public long ToUnixTime(DateTime date) { var epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.U ...
 - PhpMyAdmin隐藏数据库设置同前缀失效的问题
			
用PhpMyAdmin默认会把所有数据库都显示出来,一些如 MySQL,information_schema之类的也会显示,这样既不安全看着也不爽,隐藏掉最好. 修改 config.inc.php 或 ...
 - 持续集成Jenkins+sonarqube部署教程
			
1 引言 1.1 文档概要 本文主要介绍jenkins,sonar的安装与集成,基于ant,maven构建.用一个例子介绍jenkins的编译打包部署,代码检查.最后集成jenkins.(现阶段只是简 ...
 - java 生成二维码
			
package com.sun.erwei; import java.awt.Graphics2D;import java.awt.geom.AffineTransform;import java.a ...
 - string 数字序列大小比较
			
string 数字序列大小比较 string.compare string a = "022"; string b="1"; 比较结果 '022' < ' ...
 - 使用eclipse XML catalog绑定dtd文件
			
有时候我们想编辑struts或spring的xml配置文件的时候,输了“<”之后eclipse却没有提示关键字,这是因为eclipse需要到网络下载dtd文件而由于网络原因没下载下来所以无法提示 ...
 - 【APP测试初体验】android测试命令----adb常用命令
			
--adb shell 命令adb devices 查看设备adb shell adb shell "ls -al /system/bin" >e:\a.txtsample_ ...
 - 在windows下安装pip scrapy...
			
将 C:\Users\用户名\AppData\Local\Programs\Python\Python35\Scripts C:\Users\用户名\AppData\Local\Programs\Py ...
 - python下载时报错 Errno 10060] A connection attempt failed because the connected party did not properly respond after a period of time
			
def downloadXml(isExists,filedir,filename): if not isExists: os.mkdir(filedir) local = os.path.join( ...
 - JavaScript里利用DOM获取宽高大全
			
网页可见区域宽:document.body.clientWidth网页可见区域高:document.body.clientHeight网页可见区域宽:document.body.offsetWidth ...