标签:
一、它为什么而存在
设计一个数据库时,可将一个列的数据类型定义成一个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从可空实例中取出值,并对其进行装箱。
标签:
原文地址:http://www.cnblogs.com/JustYong/p/4756286.html