判断相等
一:对于相等,有如下两种概念:
1)值相等。例如:两个整数1、我们可以说它们值相等,两个字符串"A",我也可以说它们值相等。值相等的概念适用于预定义的值类型
和string类型。
2)引用相等。对于引用相等、需要注意其比较不是两个“对象”本身,而是两个“对象引用”,如果两个“对象引用”引用的是同一个
对象则我们说他们引用相等。引用相等适用于string类型以外的引用类型。
换句话说,对于不同的类型,相等的概念是不一样的。预定义的值类型和string类型,我们需要判断相等只要判断其值是否相等就可以。而
string类型以外的引用类型则需要判断两个对象引用是否是同一个引用。
二、判断相等有两种通用的方式:== 运算符和 System.Object.Equals(Object) 方法,那么这两种通用的方式之间又什么区别呢?
需要明确一下,== 运算符是可以被重载的,equals方法是虚方法,是可以被覆写的。
|
预定义的值类型和 string类型 |
string类型外的引用类型 |
== 运算符 |
判断值相等 |
判断引用相等 |
|
|
|
Equals方法 |
先判断类型,是否一致,如果不一致, 则return false。
判断值相等 |
|
object的Equals方法默认实现:
public virtual bool Equals(object obj) { return (this == obj); }
值类型的Equals方法已经被重写了。
static void Main(string[] args) { string str1 = new string(new char[] { 'a', 'b', 'c' }); string str2 = new string(new char[] { 'a', 'b', 'c' }); object obj1 = str1; object obj2 = str2; Console.WriteLine("第一组"); Console.WriteLine(str1 == str2); Console.WriteLine(str1.Equals(str2)); Console.WriteLine("第二组"); Console.WriteLine(obj1 == obj2); Console.WriteLine(obj1.Equals(obj2)); int n1 = 5; long n2 = 5;
Console.WriteLine("第三组"); Console.WriteLine(n1 == n2); Console.WriteLine(n1.Equals(n2)); Console.Read(); }
运行结果如下图:
我想第一组应该是没有问题的。
第二组 == 运算符,由于 obj1 和 obj2 都是非string的引用类型,所以应该判断引用相等。由于 obj1 和 obj2 引用的是两个不同的string
对象,所以结果为False。
第二组 Equals 方法, obj1 和 obj2 保存的引用是 str1 和 str2。str1 是string类型,此时该判断会调用str1对象的Equals方法,判断
值相等。(Equals是虚方法,虚方法的调用,后续会有专门的随笔进行介绍。)
第三组Equals方法, n1是预定义的值类型,由于 n2 和 n1的类型不一致,所以结果为 False 。
三、在内存角度看待 == 运算符和 Equals 方法
值类型存储在栈中,引用类型的变量在栈里只存储引用类型变量的地址,而其本身存储在堆中。
对于预定义的值类型:== 运算符和 Eqauls方法都是判断栈中的内容是否相等。
对于非string的引用类型而言:== 运算符是判断栈中的内容是否相等, Equals方法是判断堆中的内容是否相等。
四、Object.ReferenceEquals 方法 和 Object.Equals 方法 (Object, Object)
1、Object.Equals 方法 (Object, Object):实现可表示为:
public static bool Equals(object objA, object objB) { if (objA == objB) { return true; } if((objA != null ) && (objB != null)) { return objA.Equals(objB); } return false; }
因此其判断结果取决于三个条件:
1)是否是同一实例
2)是否都为null(可以解决两个值均为null的对象判等问题)
3)第一个参数的Equals方法实现
2、ReferenceEquals 方法
public static bool ReferenceEquals(object objA, object objB) { return objA == objB; }
即判断两个对象是否为同一个引用。
五、判断字符串相等
除了 == 运算符和 Equals方法外,还有string.Compare方法。