可为空的值类型(Nullable<T>)需要注意的地方

作者:袖梨 2022-06-25

可为空的值类型(nullable)需要注意的地方
第一,它是一个结构类型,值类型

其实下面的这个变量声明就是可为空的值类型

int? number = 100;

但是number是真的值类型吗,我们使用typeof(int?)看看他的类型吧,

system.nullable`1[system.int32]

nullable的声明如下:

public struct nullable where t : struct

声明很清楚是struct,这样我们就明白了,原来int?是值类型啊。

为了验证,我们使用number.gettype()来看看类型是什么,答案是system.int32。

所以,能被赋值为null的,不一定是引用类型啊。

下面的代码在控制台中打印的结果是100,而不是101:

        public void test()
        {
            int? number = 100;
            changevalue(number);
            console.writeline(number);
        }
        void changevalue(int? number)
        {
            number += 1;
        }
另外,大家看看下面这个代码行:

int number = new nullable();
number变量的值居然是null。

有的朋友会说nullable是结构类型,所以装箱和拆箱是符合值类型特点的,我认为这句话是错误的。

比如:

            object o = null;
            int? a = (int?)o;
            int b = (int)o;a是可以被拆箱为null值的,而b这行代码运行时是要抛出nullreferenceexception异常的。

第二,nullable可以转换为接口类型

本身nullabe没有实现任何接口,但是请看下面的代码段:

int32? n = 5; 
int32 result = ((icomparable) n).compareto(5);  // compiles & runs ok 
console.writeline(result);                      // 0
这是clr为开发人员提供的福利啊,呵呵。

如果没有这个福利的话,我们就写出下面的代码才能实现同样的过程:

int32 result = ((icomparable) (int32) n).compareto(5); 第三,??操作符

顺便提提这个??(null-coalescing operator)操作符,当操作符左边的表达式为空时,返回操作符右边的值;如果操作符左边表达式值不为空时,返回操作符左边表达式值。

??操作符给我们的编码带来了很多的便利,是我们的代码更为简练,可读性更强,看下面几个示例:

private static void nullcoalescingoperator() { 
   int32? b = null; 
 
   // the line below is equivalent to: 
   // x = (b.hasvalue) ? b.value : 123 
   int32 x = b ?? 123;     
   console.writeline(x);  // "123" 
 
   // the line below is equivalent to: 
   // string temp = getfilename(); 
   // filename = (temp != null) ? temp : "untitled"; 
   string filename = getfilename() ?? "untitled"; 
}还可以连写:

string s = somemethod1() ?? somemethod2() ?? "untitled";

还可以用在lamda表达式里面,增强可读性:

func f = () => somemethod() ?? "untitled";

相关文章

精彩推荐