在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
在程序开发中,有时候需要值类型也为可空类型,比如,在数据库中,我们可以把一个日期Datetime设置为null。 在C# 2.0中就出现了可空类型,允许值类型也可以为空(null),可空类型的实现基于C#泛型。
可空类型基本知识
可空类型的核心是System.Nullable<T>,同时静态类System.Nullable为可空类型提供了很多实用的方法。下面分别看看可空类型的这两个重要组成部分。
System.Nullable<T>
从上面的图中可以看到关于System.Nullable<T>的一些关键点:
对于任何具体的可空类型来说,T的类型为可空类型的基础类型(underlying type),例如Nullable<int>的基础类型就是int。 通过上面代码还可以看到,Nullable<T>有两个重要的属性,HasValue和Value。通过它们可以了解可空类型是怎么工作的:
下面看一个可空类型的简单例子,进一步了解一下可空类型: static void Display(Nullable<int> x) { Console.WriteLine("HasValue: {0}", x.HasValue); if (x.HasValue) { Console.WriteLine("Value: {0}", x.Value); Console.WriteLine("Explicit conversion: {0}", (int)x); } Console.WriteLine("GetValueOrDefault(): {0}", x.GetValueOrDefault()); Console.WriteLine("GetValueOrDefault(10): {0}", x.GetValueOrDefault(10)); Console.WriteLine("ToString(): {0}", x.ToString()); Console.WriteLine("GetHashCode(): {0}", x.GetHashCode()); Console.WriteLine(); } static void Main(string[] args) { Nullable<int> x = 5; Display(x); x = new Nullable<int>(9); Display(x); x = new Nullable<int>(); Display(x); Console.Read(); } 程序的输出为: 通过这段代码可以看到HasValue和Value的使用,以及Nullable<T>中一些常用的方法。 注意,在这段代码中,下面两句的IL代码是一样的: C#代码 Nullable<int> x = 5; x = new Nullable<int>(9); IL代码 IL_0004: call instance void valuetype [mscorlib]System.Nullable`1<int32>::.ctor(!0) IL_0015: call instance void valuetype [mscorlib]System.Nullable`1<int32>::.ctor(!0) 这里涉及了包装(wrapping)和拆包(unwrapping)的概念:将T的一个实例转换成Nullable<T>的一个实例的过程在C#中成为包装,相反的过程成为拆包。这个概念跟装箱和拆箱不一样,后面会看到Nullable<T>的装箱和拆箱。
Nullable<T>的装箱和拆箱
对于Nullable<T>的装箱和拆箱可以概括为:
看一个关于可空类型装箱和拆箱的例子: static void Main(string[] args) { Nullable<int> x = 5; //有值的可空类型装箱 object boxed = x; Console.WriteLine(x.GetType()); //拆箱为普通类型 int normal = (int)boxed; Console.WriteLine(normal); //拆箱为可空类型 x = (Nullable<int>)boxed; Console.WriteLine(x); x = new Nullable<int>(); //空的可空类型装箱 boxed = x; Console.WriteLine(boxed == null); //拆箱为可空类型 x = (Nullable<int>)boxed; Console.WriteLine(x.HasValue); } 输出:
System.Nullable
下面两个方法是比较方法: public static int Compare<T>(T? n1, T? n2) where T : struct public static bool Equals<T>(T? n1, T? n2) where T : struct 下面这个方法用来获得可空类型的基础类型: public static Type GetUnderlyingType(Type nullableType)
可空类型语法糖
下面的C#语句具有相同的IL代码。 Nullable<int> x = 5; int? y = 5; IL_0004: call instance void valuetype [mscorlib]System.Nullable`1<int32>::.ctor(!0) IL_000d: call instance void valuetype [mscorlib]System.Nullable`1<int32>::.ctor(!0)
使用null进行赋值和比较
对于下面的代码,通过IL可以发现"x == null"实际调用的是HasValue属性进行比较。 int? x = null; Console.WriteLine(x == null); IL_000b: call instance bool valuetype [mscorlib]System.Nullable`1<int32>::get_HasValue()
总结
在使用中,我们可以直接使用?修饰符来创建可空值类型。
|
请发表评论