zoukankan      html  css  js  c++  java
  • [CLR via C#]可空值类型

    一、它为什么而存在

          设计一个数据库时,可将一个列的数据类型定义成一个32位整数,并映射到FCL的Int32数据类型。但是,数据库中的一个列可能允许值为空,也就是说,该列在某一行上允许没有任何值。用.NET Framework处理数据库数据时可能变得相当困难,因为在CLR中,没有办法将一个Int32值表示成null。

    二、它到底是什么

    为了解决这个问题,Microsoft在CLR中引入了可空值类型的概念。为了理解它们是如何工作的,先来看一下System.Nullable<T>结构,注意它是一个值类型。

     1     [Serializable]
     2     public struct Nullable<T> where T : struct
     3     {
     4         private bool hasValue;
     5 
     6         internal T value;
     7 
     8         public bool HasValue
     9         {
    10             get
    11             {
    12                 return this.hasValue;
    13             }
    14         }
    15         public T Value
    16         {
    17             get
    18             {
    19                 if (!this.HasValue)
    20                 {
    21                     throw new InvalidOperationException("Nullable object must have a value.");
    22                 }
    23                 return this.value;
    24             }
    25         }
    26 
    27         public Nullable(T value)
    28         {
    29             this.value = value;
    30             this.hasValue = true;
    31         }
    32    
    33         public T GetValueOrDefault()
    34         {
    35             return this.value;
    36         }
    37         public T GetValueOrDefault(T defaultValue)
    38         {
    39             if (!this.HasValue)
    40             {
    41                 return defaultValue;
    42             }
    43             return this.value;
    44         }
    45         public override bool Equals(object other)
    46         {
    47             if (!this.HasValue)
    48             {
    49                 return other == null;
    50             }
    51             return other != null && this.value.Equals(other);
    52         }
    53         public override int GetHashCode()
    54         {
    55             if (!this.HasValue)
    56             {
    57                 return 0;
    58             }
    59             return this.value.GetHashCode();
    60         }
    61         public override string ToString()
    62         {
    63             if (!this.HasValue)
    64             {
    65                 return "";
    66             }
    67             return this.value.ToString();
    68         }
    69         public static implicit operator T?(T value)
    70         {
    71             return new T?(value);
    72         }
    73         public static explicit operator T(T? value)
    74         {
    75             return value.Value;
    76         }
    77     }

    1.当使用Nullable<Int32> x = 5时,实际上调用了Nullable的有参构造函数来初始化值类型。

    2.当使用Nullable<Int32> x = null时,实际上调用了Nullable的无参构造函数来初始化值类型。

    三、C#对可空值类型的支持

    C#允许用问号表示法来声明并初始化可空值类型,如Int32? x = 5,相当于Nullable<Int32> x = new Nullable<Int32>(5);

    1.C#允许开发人员在可空实例上执行转换和转型

    Int32? a = 5;

    //通过查看IL可知,实际上是获取了Value属性的值再赋值给b。所以如果a等于Null时,下面一行代码会抛出异常。

    Int32 b = (Int32)a;

    //通过查看IL可知,实际上是调用了GetValueOrDefault方法获取值,然后再调用new Nullable<Double>构造函数初始化变量。 

    Double? c = a;

    四、C#的空接合操作符

    "??",获取两个操作数,假如左边的操作数不为空,就返回这个操作数的值,否则返回右边操作数的值。

    五、CLR对可空值类型的特殊支持

    1.可空值类型的装箱

    当CLR对一个可空值类型进行装箱时,会检查它是否为空,如果为空,则CLR不进行任何装箱,并返回空值。如果可空实例不为空,CLR从可空实例中取出值,并对其进行装箱。

  • 相关阅读:
    Repeater嵌套,增删改查综合运用
    DataSet用法(三) 操作数据
    创建DataSet
    DataSet用法(一)
    DataSet使用方法
    DataSet用法(二)
    Repeater嵌套绑定Repeater
    DataBinder.Eval用法
    简单谈谈DataSet与DataTable的区别
    Repeater嵌套的两种方案
  • 原文地址:https://www.cnblogs.com/JustYong/p/4756286.html
Copyright © 2011-2022 走看看