C# 几个特殊运算符的理解和Nullable<T> 的研究

 

可空值类型和?运算符

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

1             Nullable<Int32> count = 3;
2             
3             int? i = 1;
4             
5             bool? flag = false;
6 
7             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 是不能直接来用=赋值的(编译器报错),那么他们在使用过程中就进行类型转换,例如

1             int x = 9;
2             int? a = x; //正确
3             int? z = (int?)x;//正确
4             //int y = a; //Error Cannot implicitly convert type 'int?' to 'int'
5             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>,

1             object obj1 = null;
2             object obj2 = 1;
3             int? o1 = (int?)obj1;
4             int? o2 = (int?)obj2;
5             int i1 = (int)obj1;//NullException
6             int i2 = (int)obj2;

 

Nullable<T>的类型

下面我们来看一下Nullable<T>的类型,可以使用代码查看,

1  
2             Nullable<Int32> count = 3;
3             Console.WriteLine(count.GetType());//"System.Int32"

为什么Nullable<Int32>的类型和Int32的类型相同呢?如果他们真的相同,为什么不能直接赋值,要进行强制转换呢?这就是CLR对我们撒谎了。

??运算符

最后我们了解一下运算符“??”(null-coalescing operator 空接合运算符),他是一个类似于?:运算符的的运算符,a??b 表示如果a 不等于null,则返回a, 否则返回b。对于使用不使用,什么时候使用 仁者见仁智者见智,所以不多说,只给出一个例子。

1             Int32? temp = null;
2             Int32 temp1 = temp ?? 123; //Equals temp1 = temp.HasValue ? temp.Value:123;

 

 

转载于:https://www.cnblogs.com/anthonyBlog/p/3197994.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值