C#中可以为null的类型

  在C#中,我们有各种预定义的类型可以使用,比如int,int实际上是System.Int32的一个实例。它的取值有一个范围。如果我们的int从某个地方接收到一个null,比如数据库,或者任何其他地方。那么赋值肯定会失败。而且会产生编译错误或者运行时错误。当然我们可以处理这样的异常或者做一个些防范。但是我们有一种更好的选择,就是让我们的基本数据类型除了可以取正常范围的值之外还能为null,这样就不会产生异常,我们只需要在要使用这个值的时候检测一下值是否非空就可以使用了。那么这个类型就是System.Nullable<T>.简写为T?.T为我们要使用的类型,但是不能为引用类型,事实上也不需要是引用类型,因为引用类型本身就可以为null。如果有兴趣可以使用工具反射System.Nullable<T>看看它的实现代码。

  使用可以为null的类型需要注意几点

  1,可以使用T.GetValueOrDefault属性返回该基础类型所附的值或者默认值

  2,可以使用HasValue测试T是否有值

  3,可以只用Value取得值,如果Hasvalue返回true

  4,??运算符,如果将前值为空且可以为空的类型的值赋给不能为空的类型,将应用此默认值。

  5,不允许嵌套使用可以为nll的类型System.Nullable<System.Nullable<T>>将不被允许

  6,T?不能用做条件语句。

  7,把可以为空的类型显示转换为常规类型的时候,可以使用强制转换或者 Value属性,但是最好判断一下是否有值,把常规类型转换为可以为null类型的时候都是隐式转换,直接复制

  8,在执行值类型运算的时候,如果其中一个数为null,则计算结果也为null,如果不为null,则按照正常逻辑计算。在比较可空类型的时候,如果有一个数为null,则结果始终为false。如果两个数都为null,则比较相等返回true。

  9,可空类型装箱的时候,如果不为null,则正常装箱,但是装箱的是基础类型T,而不是Nallable<>.如果不包含值,那么直接赋值为null,不进行装箱。

  

  我们来看看实际使用方法

            Nullable<int> canBeNullInt = null;
            int? otherInt = null;

  这样就定义了一个可以为null的int,两种方法都可以。我们也可以使用各种属性

        static void Main(string[] args)
        {
            Nullable<int> canBeNullInt = null;
            int? otherInt = 10;

            int result = canBeNullInt.GetValueOrDefault();

            Console.WriteLine(result);

            if (otherInt.HasValue)
            {
                Console.WriteLine(otherInt.Value);
            }
            else
            {
                Console.WriteLine("otherInt==null");
            }

            Console.Read();
        }

  下面来看看可以为null的类型跟常规类型之间的转换 

 static void Main(string[] args)
        {
            Nullable<int> canBeNullInt = null;
            int? otherInt = 10;

            int rInt = otherInt.Value;
            int rInt2=0;
            try
            {
                rInt2 = (int)canBeNullInt;
                Console.WriteLine(rInt2);
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }

            Console.WriteLine(rInt);
            
            Console.Read();
        }

  可以强制转换,也可以隐身转换,强制转换的时候最后测试一下,变量是否包含值。至于隐式转换就很简单了

            Nullable<int> canBeNullInt = null;
            canBeNullInt = 2;

  来看一下可以空类型的计算

            Nullable<int> canBeNullInt = null;
           
            int? otherInt = 10;

            Console.WriteLine((canBeNullInt*10).ToString());
            Console.WriteLine(otherInt*10);

  可以得到结果,第一个操作为null,第二个操作为100.

  可空类型的比较

            int? int1 = null;
            int? int2 = 10;

            if (int2 >= int1)
            {
                Console.WriteLine("int2>=int1");
            }
            else
            {
                Console.WriteLine("int2<=int1");
            }

  结果为false,但是如果两个数都为null,而且比较相等的话,那就返回true。  

  ??运算符

  ??运算符是把一个为null的类型分配给非为null的类型时返回的默认值,注意,类型必须为null,否则将把包含的值附给非为null的类型

            int? int1 = null;
            int? int3 = 10;

            int int2 = int1 ?? 1;
            int int4 = int3 ?? 2;

            Console.WriteLine(int2);
            Console.WriteLine(int4);
            

  ??运算符也可以连接多个

            int? int1 = 2;
            int? int3 = 10;

            int int2 = int1 ?? 1;
            int int4 = int3 ?? int1 ?? 2;

  如果int1和int3都为null,则取默认值2,如果其中有一个不为null,则取不为null的这个数的值,如果都不为null,则取第一个的值。

  最后需要注意的就是对bool?类型的操作,用一张官方的图概括。 

  最后注意一点就可以了,如果要操作可以为null的类型,最好事先使用Hasvalue测试一下是否有值,免得发生异常。 

 

posted @ 2011-11-13 03:35  刘中栋  阅读(2940)  评论(0)    收藏  举报