C在C#中,对于可空类型描述为:Nullable<T>, 它表示该类型是可以为空的一个类型。它被定义为一个结构(struct)而非一个类(class),C#中对于Nullable<T>可空类型有个简单写法:T?,例如:int?。下面简单介绍Nullable<T>的用法

C

一、Nullable<T>在C#中的定义

  •  
  • C# 代码   复制
  • 
    namespace System
    {
        [Serializable]
        public struct Nullable<T> where T : struct 
        {
            private bool hasValue;
            internal T value;
     
            public Nullable(T value) {
                this.value = value; 
                this.hasValue = true;
            }
    
            public bool HasValue { 
                get {
                    return hasValue; 
                } 
            }
     
            public T Value { 
                get {
                    if (!HasValue) { 
                        ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_NoValue); 
                    }
                    return value; 
                }
            }
    
            public T GetValueOrDefault() { 
                return value;
            } 
    
            public T GetValueOrDefault(T defaultValue) {
                return HasValue ? value : defaultValue;
            } 
    
            public override bool Equals(object other) { 
                if (!HasValue) return other == null; 
                if (other == null) return false;
                return value.Equals(other); 
            }
    
            public override int GetHashCode() {
                return HasValue ? value.GetHashCode() : 0; 
            }
     
            public override string ToString() { 
                return HasValue ? 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<T>类型的说明

    1、Nullable<T> 类型也是一个值类型;


    2、Nullable<T> 类型包含一个Value属性用于表示基础值,还包括一个Boolean类型的HasValue属性用于表示该值是否为null ;


    3、Nullable<T> 是一个轻量级的值类型。Nullable<T>类型的实例占用内存的大小等于一个值类型与一个Boolean类型占用内存大小之和;
     

    4、Nullable<T> 的泛型参数T必须是值类型。您只能将Nullable<T>类型与值类型结合使用,您也可以使用用户定义的值类型。

    5、可空类型在基元类型正常值范围外加上了空值null。

    6、使用可空类型,接收数据库的可空字段值时更加方便。

    三、Nullable<T>的简单使用实例

  • C# 代码   复制
  • 
        Nullable<int> i = 1; //简写为:int? i = 1;
        Nullable<int> j = null;
    
        Console.WriteLine(i.HasValue);
        //输出结果:True
    
        Console.WriteLine(i.Value);
        //输出结果:1
    
        Console.WriteLine(j.HasValue);
        //输出结果:False
    
        Console.WriteLine(j.Value);
        //抛异常: System.InvalidOperationException
    
    		
  • 备注

    1、Nullable<T>的简写形式为:T?

    2、可以通过 Value 属性来获取基础类型的值。如果不为null,则将返回实际的值,否则将抛出InvalidOperationException异常;所以在调用Value属性的时,需要检查是否为null。

    四、Nullable<T>类型的转换和运算

    1、Nullable<T>类型转换

  •  
  • 
        // 从System.Int32隐式转换为Nullable<Int32> 
        int? i = 5;
    
        // 从'null'隐式转换为Nullable<Int32> 
        int? j = null;
    
        // 从Nullable<Int32>到Int32的显式转换
        int k = (int)i;
    
        // 基础类型之间的转换
        Double? x = 5; // 从Int到Nullable<Double> 的隐式转换
        Double? y = j; // 从Nullable<Int32> 隐式转换Nullable<Double>
    
    		
  • 2、Nullable<T>类型运算

    对Nullable<T> 类型使用操作符,与包含的基础类型使用方法相同。

    (1)、一元运算符(++、--、 - 等),如果Nullable<T>类型值是null时,返回null;
    (2)、二元运算符(+、-、*、/、%、^等)任何操作数是null,返回null;
    (3)、对于==运算符,如果两个操作数都是null,则表达式计算结果为true,如果任何一个操作数是null,则表达式计算结果为false;如果两者都不为null,它照常比较。
    (4)、对于关系运算符(>、<、>=、<=),如果任何一个操作数是null,则运算结果是false,如果操作数都不为null,则比较该值。

  •  
  • 
        int? i = 5;
        int? j = null;
    
        // 一元运算符
        i++; // i = 6 
        j = -j; // j = null
    
        // 二元运算符
        i = i + 3; // i = 9 
        j = j * 3; // j = null;
    
        // 等号运算符(==、!=)
        var r = i == null; //r = false
        r = j == null; //r = true
        r = i != j; //r = true
    
        // 比较运算符(<、>、<=、>=)
        r = i > j; //r = false
    
        i = null;
        r = i >= j; //r = false,注意,i=null、j=null,但是>=返回的结果是false
    
    		
  • 五、Nullable<T>的装箱与拆箱

    1、当一个Nullable<T>类型的实例装箱时,CLR会检查实例的HasValue属性:如果是true,则将实例Value属性的值进行装箱后返回结果;如果返回false,则直接返回null,不做任何的处理。


    2、在拆箱处理时,与装箱处反。CLR会检查拆箱的对象是否为null,如果是直接创建一个新的实例 new Nullable<T>(),如果不为null,则将对象拆箱为类型T,然后创建一个新实例 new Nullable<T>(T)。

  •  
  •  
  • 
        int? n = null;
        object o = n; //不会进行装箱操作,直接返回null值
    
        Console.WriteLine("o is null = {0}", object.ReferenceEquals(o, null));
        //输出结果:o is null = True
    
    
        n = 5;
        o = n; //o引用一个已装箱的Int32
    
        Console.WriteLine("o's type = {0}", o.GetType());
        //输出结果:o's type = System.Int32
    
        o = 5;
    
        //将Int32类型拆箱为Nullable<Int32>类型
        int? a = (Int32?)o; // a = 5 
        //将Int32类型拆箱为Int32类型
        int b = (Int32)o; // b = 5
    
        // 创建一个初始化为null
        o = null;
        // 将null变为Nullable<Int32>类型
        a = (Int32?)o; // a = null 
        b = (Int32)o; // 抛出异常:NullReferenceException
    
    		
  • 六、Nullable<T>的ToString()方法

    当调用Nullable<T>类型的ToString()方法时,如果HasValue属性的值为false,则返回String.Empty,如果该属性的值为true,则调用的逻辑是Value.ToString()。

  •  
  •  
  • 
        int? i = 10;
        Console.WriteLine(i.ToString());
        //输出结果:10
    
        i = null;
        Console.WriteLine(i.ToString() == string.Empty);
        //输出结果:True
    
    		
  • 标签: