标签:
==运算符与基元类型我们分别用两种方式比较两个整数,第一个使用的是Equals(int)方法,每二个使用的是==运算符:
1 class Program 2 { 3 static void Main(String[] args) 4 { 5 int num1 = 5; 6 int num2 = 5; 7 8 Console.WriteLine(num1.Equals(num2)); 9 Console.WriteLine(num1 == num2);10 }11 }
运行上面的示例,两个语句出的结果均为true。我们通过ildasm.exe工具进行反编译,查看IL代码,了解底层是如何执行的。
如果您以前从来没有接触过IL指令,不过没关系,在这里您不需要理解所有的指令,我们只是想了解这两个比较方式的差异。
您可以看到这样一行代码:
1 IL_0008: call instance bool [mscorlib]System.Int32::Equals(int32)在这里调用的是int类型Equals(Int32)方法(该方法是IEquatable<Int>接口的实现)。
现在再来看看使用==运算符比较生成的IL指令:
1 IL_0015: ceq您可以看到,==运行符使用的是ceq指令,它是使用CPU寄存器来比较两个值。C#==运算符底层机制是使用ceq指令对基元类型进行比较,而不是调用Equals方法。
==运算符与引用类型修改上面的示例代码,将int类型改为引用类型,编译后通过ildasm.exe工具反编译查看IL代码。
1 class Program 2 { 3 static void Main(String[] args) 4 { 5 Person p1 = new Person(); 6 p1.Name = "Person1"; 7 8 Person p2 = new Person(); 9 p2.Name = "Person1";10 11 Console.WriteLine(p1.Equals(p2));12 Console.WriteLine(p1 == p2);13 }14 }
上述C#代码的IL代码如下所示:
我们看到p1.Equals(p2)代码,它是通过调用Object.Equals(Object)虚方法来比较相等,这是在意料之中的事情;现在我们来看==运算符生成的IL代码,与基元类型一致,使用的也是ceq指令。
==运算符与String类型接来下来看String类型的例子:
1 class Program 2 { 3 static void Main(String[] args) 4 { 5 string s1 = "Sweet"; 6 string s2 = String.Copy(s1); 7 8 Console.WriteLine(ReferenceEquals(s1, s2)); 9 Console.WriteLine(s1 == s2);10 Console.WriteLine(s1.Equals(s2));11 }12 }
上面的代码与我们以前看过的非常相似,但是这次我们使用String类型的变量。我们建一个字符串,并付给s1变量,在下一行代码我们创建这个字符串的副本,并付给另一个变量名称s2。
运行上面的代码,在控制台输出的结果如下: