• 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;
  • 相关阅读:
    <script>元素
    女朋友问什么是动态规划,应该怎么回答?
    从输入URL到页面展示,这中间都发生了什么?
    TypeScript之父:JS不是竞争对手,曾在惧怕开源的微软文化中艰难求生
    Flash 终将谢幕:微软将于年底停止对 Flash 的支持
    尤雨溪:TypeScript不会取代JavaScript
    JVM参数设置、分析(转发)
    -XX:PermSize -XX:MaxPermSize 永久区参数设置
    堆的分配参数
    -Xmx 和 –Xms 设置最大堆和最小堆
  • 原文地址:https://www.cnblogs.com/anthonyBlog/p/3197994.html
Copyright © 2020-2023  润新知