也谈值类型与null的判等比较

园子里有两篇精彩的文章《谈谈值类型与null的判等比较!》和《再谈值类型和null的比较》,周雪峰同学从编译的角度给出了他的思路。

首先我们回顾一下代码(这里根据需要做了简化) : 

 1 using System;
 2 
 3 namespace StructOperatorDemo
 4 {
 5     class Program
 6     {
 7         struct MyStruct
 8         {
 9             public int Value;
10 
11             public MyStruct(int fValue)
12             {
13                 this.Value = fValue;
14             }
15 
16             public static bool operator !=(MyStruct s1, MyStruct s2)
17             {
18                 return s1.Value != s2.Value;
19             }
20             public static bool operator ==(MyStruct s1, MyStruct s2)
21             {
22                 return s1.Value == s2.Value;
23             }
24         }
25 
26         static void Main(string[] args)
27         {
28             MyStruct myStruct = new MyStruct();
29 
30             if (myStruct == null)
31             {
32                 Console.WriteLine("OMG, that is impossible!");
33             }
34         }
35     }
36 }


之前的代码用.Net2.0以及之后的编译器可以编译通过,但是2.0 之前的编译器去编译是无法通过的,它会明确告示你struct不能跟null比较。这是什么原因呢? 

我们再看看这段代码: 

1 int x = 1;
2 
3 if (x == 1.2)
4 {
5     Console.WriteLine("Emmm, I think it is not possible.");
6 

 

就这段代码而言,虽然int 本身并不包含对double类型判等比较的重载,但无论是新的还是老的.Net编译器都可以编译通过(当然还有加上相关必要的代码),因为编译器在编译时会将x和1.2转换成double 来进行比较。对了,编译器自己会做隐式转换。

所以第一段代码到了.Net2.0就可以编译通过,因为二者都可以被转换成MyStruct?进行比较。而在.Net 2.0之前,编译器还不知道什么是Nullable Type呢!

当然,编译器还做了别的优化,比如例子中的情况根本不可能返回true,那么编译器直接忽略随后的相关代码。

就象周雪峰同学总结的那样,这不是一个bug,而是故意设计的。而真相则是对Nullable Type隐式转换的一个延伸,虽然struct == null不可能发生,但是它是“合法”的 : ) 

 

 

posted on 2010-02-03 21:59  Stephen Zeng  阅读(1329)  评论(0)    收藏  举报

导航