可空值类型和?运算符

谈到运算符,大家一定很熟悉,但是对所有的运算符都能掌握吗? 看了下面代码再回答。

             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> 的研究的更多相关文章

  1. c语言 &取地址运算符的理解

    对于c语言中的&运算符,百度百科是这样定义的:(&p)则是这样一种运算,返回当时声明p 时开辟的地址:但是根据我对代码的观察,我觉得&运算符不只是返回地址的功能: 例如: in ...

  2. JS按位非(~)运算符与~~运算符的理解分析

    按位非运算符,简单的理解就是改变运算数的符号并减去1,当然,这是只是简单的理解能转换成number类型的数据. 那么,对于typeof var!==”number”的类型来说,进行运算时,会尝试转化成 ...

  3. js中得~~是什么意思/JS按位非(~)运算符与~~运算符的理解分析

    其实是一种利用符号进行的类型转换,转换成数字类型 ~~true == 1 ~~false == 0 ~~"" == 0 ~~[] == 0 ~~undefined ==0 ~~!u ...

  4. Java中移位操作运算符的理解

    java中的移位运算符有三种: 1. <<: 左移 2. >>: 右移 3. >>>: 无符号右移 使用方法:左移就是将左边的操作数在内存中的二进制数据左移指 ...

  5. php中&运算符的理解与使用

    php的引用(就是在变量或者函数.对象等前面加上&符号) 在PHP 中引用的意思是:不同的名字访问同一个变量内容. 变量的引用 PHP 的引用允许你用两个变量来指向同一个内容 例一: < ...

  6. C语言中关于逗号运算符的理解

    在C语言中运算符有很多,包括算数运算符.关系运算符.赋值运算符.位运算符.逻辑运算符.三目运算符.sizeof运算符.逗号运算符等等,那今天我们就重点来给大家讨论一下关于逗号运算符的一些运算规则. 首 ...

  7. Java 位运算符 深入理解

    在Java中存在着这样一类操作符,是针对二进制进行操作的.它们各自是&.|.^.~.>>.<<.>>>几个位操作符.不管是初始值是依照何种进制,都会换 ...

  8. 短路运算符&&、或运算符||的理解

    一.短路运算符&& 1.当只有两个表达式的时候(如a&&b),先看第一个表达式转换成布尔值的结果若为真,那么再看第二个表达式转换成布尔值的结果,就可以返回该表达式的值了 ...

  9. memcache 线程深入理解分析 及 源码研究

    http://blog.csdn.net/huithe/article/details/8006186

随机推荐

  1. SqlParameter 中 top 的使用

    public DataTable GetAdminTopDCSCheckReport(int top) { StringBuilder strSql = new StringBuilder(); st ...

  2. Python学习笔记——基础篇【第六周】——PyYAML & configparser模块

    PyYAML模块 Python也可以很容易的处理ymal文档格式,只不过需要安装一个模块,参考文档:http://pyyaml.org/wiki/PyYAMLDocumentation 常用模块之Co ...

  3. css3制作3d旋转相册

    此处只是记录,解析可见原文:http://www.cnblogs.com/skyblue-li/p/6092799.html <!DOCTYPE html> <html xmlns= ...

  4. 5、范围标签<fieldset></fieldset>

    <fieldset style="border:0;border:1px solid red;"> <legend style="background- ...

  5. informix数据迁移工具使用介绍

    一.dbschema  USAGE:     dbschema [-q] [-t tabname] [-s user] [-p user] [-r rolename] [-f procname]    ...

  6. 【Python之路】第十一篇--CSS

    css CSS是Cascading Style Sheets的简称,中文称为层叠样式表,用来控制网页数据的表现,可以使网页的表现与数据内容分离. 一.css的四种引入方式 1.行内式 行内式是在标记的 ...

  7. wxWidgets显示视频

    wxWidgets中似乎没有专门用于显示视频的控件(虽然有wxWidgets本身的openGL控件wxGLCANVAS,但是我没有去试--) 按照这篇文章所讲的,从wxPanel继承出一个DrawPa ...

  8. Python基础篇-day6

    本节简介: 1.模块1.1 时间模块1.2 random模块1.3 shutil模块1.4 shelve模块1.5 XML模块1.6 ConfigParser模块1.7 hashlib模块1.8 lo ...

  9. ios9 新关键字 __kindof 等(etc) 小结

    首先__kindof:规定参数为UITableViewCell(举例)这个类或者其子类.比如说一个NSArray<UIView *>*,如果不加__kindof,这个数组只能有UIView ...

  10. Android:自定义Dialog大小,显示圆角

    经过测试,可以使用. ----------------------------------------------------------- AlertDialog.Builder builder = ...