也谈值类型与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 }
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 }
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) 收藏 举报
浙公网安备 33010602011771号