C#:引用类型和值类型的相等比较
- 引用类型的相等比较
System.Object定义了3个不同的方法来比较对象的相等性:ReferenceEquals()和Equals()的两个版本。再加上比较运算符,实际上有4种进行相等比较的方式。
- ReferenceEquals()方法
public static bool ReferenceEquals(object objA, object objB)
ReferenceEquals()是一个静态方法,测试两个引用是否指向类的同一个实例,即两个引用是否包含内存中的相同地址。作为静态方法,它不能重写,所以只能使用System.Object的实现代码。如果提供的两个引用指向同一个对象实例,ReferenceEqualsa()总是返回true,否则就返回false,但是它认为null等于null。
1 SomeClass x, y; 2 x = new SomeClass(); 3 y = new SomeClass(); 4 bool B1 = ReferenceEquals(null, null); //return true 5 bool B2 = ReferenceEquals(null, x); //return false 6 bool B3 = ReferenceEquals(x, y); //return false because x and y point to different objects
- 虚拟的Equals()方法
public virtual bool Equals(object obj)
返回一个值,该值指示当前的Object是否等于当前的Object
Equals的默认实现仅支持引用相等,但派生类可重写此方法以支持值相等
在下面的列表中,x,y,z表示不为空引用:
(1)除涉及浮点型的情况外,x.Equals(x)都返回true
(2)x.Equals(y)返回与y.Equals(x)相同的值
(3)如果x和y都为NaN,则x.Equals(y)返回true
(4)当且仅当x.Equals(z)返回true时,(x.Equals(y)&&y.Equals(z))才返回相同的值
(5)只要不修改x和y引用的对象,对x.Equals(y)的相继调用将返回相同的值
(6)x.Equals(null)返回false
1 using System; 2 3 public class Sample { 4 void Method() { 5 Object Obj1 = new Object(); 6 Object Obj2 = new Object(); 7 Console.WriteLine(Obj1.Equals(Obj2)); //===> false 8 Obj2 = Obj1; 9 Console.WriteLine(Obj1.Equals(Obj2)); //===> true 10 } 11 }
- 静态的Equals()方法
public static bool Equals(object objA, object objB)
如果objA是与objB相同的实例,或者如果两者均为空引用,或者如果objA.Equals(objB)返回true,则为true,否则为false
2. 值类型的相等比较
在进行值类型的相等比较时,采用与引用类型相同的规则:ReferenceEquals()用于比较引用,Equals()用于比较值。最大的区别是,值类型需要装箱才能把它们转换为引用,才能对它们执行方法。
ReferenceEquals()在应用值类型时,总是返回false,因为为了调用这个方法,值类型需要装箱到对象中。即使使用下面的代码:
bool b = ReferenceEquals(v, v); //v is a variable of some value type
也会返回false,因为在转换每个参数时,v都会被单独装箱。
3. 比较运算符比较
==运算符用于比较两个操作数是否相对。对于基本数据类型,就不用多说了,没有太大问题
1 string s1="test"; 2 string s2=string.copy(s1); 3 Console.WriteLine(s1==s2); //===>true 4 Console.WriteLine((object)s1==(object)s2); //===>false
1 string s1="test"; 2 string s2=s1; 3 或string s2="test"; 4 Console.WriteLine(s1==s2); //===>true 5 Console.WriteLine((object)s1==(object)s2); //===>true