• C# 可空值类型


         我们知道,值类型的变量永远不会为null,但在数据库中的一个列可能允许值为空,但在CLR中没有办法将INT32值表示成null.

         为了解决这个问题,CLR中引入了可空值类型,为了理解它是如何工作的,先来看看FCL中定义的system.Nullable<T>结构。

    一、可空值类型的代码

       

    public struct Nullable<T> where T : struct
       { 
           //两个字段表示状态
           private Boolean hasValue = false; //假定null
           internal T value = default(T);//假定所有位都为O
           
           public Nullable(T value)
           {
               this.value = value;
               this.hasValue = true;
           }
    
           public Boolean HasValue { get { return hasValue; } }
    
           public T Value {
               get {
                   if (!hasValue)
                   {
                       throw new InvalidOperationException("可空对象必须有值。");
                   }
                   return value;
               }
           }
    
           public T GetValueOrDefault()
           {
               return value;
           }
    
           public T GetValueOrDefault(T defaultValue)
           {
               if (!hasValue) return defaultValue;
               return value;
           }
    
           //重载equals方法
           public override bool Equals(object obj)
           {
               if (!HasValue) return (obj == null);
               if (obj == null) return false;
               return value.Equals(obj);
           }
    
           //重载toString()方法
           public override string ToString()
           {
               if (!HasValue) return "";
               return value.ToString();
           }
    
           public static implicit operator Nullable<T>(T value)
           {
               return new Nullable<T>(value);
           }
    
           public static explicit operator T(Nullable<T> value)
           {
               return value.Value;
           }
    
       }

        可以看出,可空类型是一个结构类型,也就是说本身是一个值类型,实例仍然是在栈上,Nullable的类型参数被约束为struct,也就是说这个类型是为了值类型而设定的。

    二、可空值类型的使用

          我们要在代码中使用一个可空的Int32,就可以像下面这样写:

    Nullable<Int32> x = 5;
            Nullable<Int32> x = null;

         但是在C#中一般是这样写

    int? x = 5;
    int? x = null;

      三、合并操作符

    C# 提供了一个空接合操作符,即??操作符,假如左边的不为null,就返回这个操作数,如果左边的为null,就返回右边的操作数。

    下面两行代码是等价的

    int? b = null;
    int a = (b.HasValue) ? b.Value : 123;
    int a = b ?? 123;

    四、可空类型的装箱和拆箱

    装箱:当CLR对可空类型进行装箱时,会检查它是否为NULL,如果是,CLR不装箱任何东西,直接返回NULL,如果可空实例不为NULL,CLR从可空实例中取出值并进行装箱,也就是说,值为5的可空类型会装箱成值为5的已装箱INT32.

    拆箱:如果已装箱的值类型引用的是NULL,要把它拆箱成可空类型,那么CLR会将可空类型的值设为NULL.

    五、可空类型调用GetType

    在可空类型上调用GetType,实际会撒谎说类型是T,而不是Nullable<T>。也就是说 Int32? x=5 ;在执行 x.GetType()时,会显示System.Int32, 而不是System.Nullable<Int32>;

  • 相关阅读:
    国王游戏
    选数
    双塔
    线段树
    树状数组及其他特别简单的扩展
    折半搜索
    VUE项目
    git_基本使用
    同源
    axios-使用
  • 原文地址:https://www.cnblogs.com/zhengwei-cq/p/8468762.html
Copyright © 2020-2023  润新知