空类型是在.NET 2.0发布的时候被引入的。使用泛型(Generics),任何值类型都可以被包装成空类型,从而可以有空值。在从前,要达到这个效果只可以通过创建一个定制的类,或者将值封装然后指定给类型对象的一个变量。
C#很快增加了对空类型的语言支持。但是VB一直在忙于从VB转换到VB.NET方面的后遗症,无暇像C#那样顾及到这一块,虽然可以用空值,但只能在 API的级别。
在9版本里,Visual Basi会对空类型全面支持。它会使用一个和C#非常接近的语法,但是语义上会有很大的区别。在C#中,比较操作要么会返回true,要么返回 false。但是在VB中,因为空值的引入,比较操作可能会返回true,false或者null等。
a
a=null, b=null | ||
Operator | C# Result | VB Result |
== | true | Nothing |
!= | false | Nothing |
> | false | Nothing |
< | false | Nothing |
>= | false | Nothing |
<= | false | Nothing |
a=1, b=null | ||
Operator | C# Result | VB Result |
== | false | Nothing |
!= | true | Nothing |
> | false | Nothing |
< | false | Nothing |
>= | false | Nothing |
<= | false | Nothing |
从上表可以看出在C#中出现的一个非常有意思的异常,在a和b都是空的时候,a==b返回的是true,但是a>=b和a<=b则返回的是false。
在遇到检查Boolean值的时候,C#是非常清晰易懂的。另外一方面,VB不得不以某种方式把自己的三状态逻辑映射到Boolean值。为了满足像IF、While和Untile这样的Boolean检查,VB是将null等同于false处理的。这会导致下面所列出的很有意思的现象:
a = null, b = null If a=b Then 'skipped Else 'this line is executed End if If Not (a=b) Then 'skipped Else 'this line is executed End if
(a=b)和Not (a=b)都返回null值,也都被认定为false。
真正地理解这些语言中细微的差别和不一致,对于使用空类型的开发人员是非常有必要的,否则就会有Bug的产生。
原文链接:http://www.infoq.com/cn/news/2007/09/VB-Nullable;jsessionid=A84377FDA3294198FE3AB5C3A76646C9