目录
一、简介
二、语法和用法
三、类型的转换和运算
四、装箱与拆箱
五、GetType()方法
六、ToString()方法
七、System.Nullable帮助类
八、语法糖
众所周知,值类型变量不能null,这也是为什么它们被称为值类型。但是,在实际的开发过程中,也需要值为null的一些场景。例如以下场景:
场景1:您从数据库表中检索可空的整数数据列,数据库中的null值没有办法将此值分配给C#中Int32类型;
场景2:您在UI绑定属性,但是某些值类型的字段不是必须录入的(例如在人员管理中的死亡日期);
场景3:在Java中,java.Util.Date是一个引用类型,因此可以将此类型的字段设置为null。但是,在CLR中,System.DateTime是一个值类型,DateTime 变量不能null。如果使用Java编写的应用程序要将日期/时间传达给在CLR上运行的Web服务,如果Java应用程序发送是null, CLR中没有供对应的类型;
场景4:在函数中传递值类型时,如果参数的值无法提供并且不想传递,可以使用默认值。但有时默认值并不是最佳的选择,因为默认值实际也传递了一个默认的参数值,逻辑需要特殊的处理;
场景5:当从xml或json反序列化数据时,数据源中缺少某个值类型属性的值,这种情况很不方便处理。
当然,我们日常工作中还有很多类似的情况。
为了摆脱这些情况,Microsoft在CLR中增加了可为空值类型的概念。为了更清楚理解这一点,我们看一下System.Nullable<T>类型的逻辑定义:
1 namespace System 2 { 3 [Serializable] 4 public struct Nullable<T> where T : struct 5 { 6 private bool hasValue; 7 internal T value; 8 9 public Nullable(T value) { 10 this.value = value; 11 this.hasValue = true; 12 } 13 14 public bool HasValue { 15 get { 16 return hasValue; 17 } 18 } 19 20 public T Value { 21 get { 22 if (!HasValue) { 23 ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_NoValue); 24 } 25 return value; 26 } 27 } 28 29 public T GetValueOrDefault() { 30 return value; 31 } 32 33 public T GetValueOrDefault(T defaultValue) { 34 return HasValue ? value : defaultValue; 35 } 36 37 public override bool Equals(object other) { 38 if (!HasValue) return other == null; 39 if (other == null) return false; 40 return value.Equals(other); 41 } 42 43 public override int GetHashCode() { 44 return HasValue ? value.GetHashCode() : 0; 45 } 46 47 public override string ToString() { 48 return HasValue ? value.ToString() : ""; 49 } 50 51 public static implicit operator Nullable<T>(T value) { 52 return new Nullable<T>(value); 53 } 54 55 public static explicit operator T(Nullable<T> value) { 56 return value.Value; 57 } 58 } 59 }