您的位置:首页 > 移动开发 > Objective-C

System.Object 类中的三个比较方法浅析

2010-06-24 01:33 211 查看
在System.Object类中有三个被设计用来进行对象比较的方法:

public virtual bool Equals(Object obj);


public static bool Equals(Object objA,Object objB);


public static bool ReferenceEquals(Object objA,Object objB);


第一个是virtual 的,后两个是 static 的。ReferenceEquals() 实现了类型的引用比较,对该函数来讲,只有应用在引用类型上时才会有意义,比较两个值类型的引用将永远返回 false ,

无论它们的值是否相等。甚至下面的代码:

int i = 0;

Console.WriteLine(object.ReferenceEquals(i, i));

输出结果也是 false . 原因是:i 是值类型的int .在传入时被自动装箱为object型变量,并且装了两次,那就是两个不同的对象啦,因此引用不相等(原因是我猜测的,存疑!)

另一个静态的 Equals() 方法的功能根据不同的类型而有所不同。它的内部判断实际分了两步:首先检查两个对象是否恒等(对于值类型来说,就是检查值内容是否相等;对于引用类型来说,就是检查引用是否相等)。然后调用其中一个参数对象的实例的Equals方法来判断两个对象是否恒等。

利用反射可以看到 静态方法 Equals() 的代码:

public static bool Equals(object objA,object objB)

{

  return ((objA == objB || (((objA != null && objB != null && objA.Equals(objB)));

}

注意这里面只有一行代码,却是别有意味。它通过一个 || 运算符,把两种情况,值类型,跟引用类型,都包含了进去。一一分析:

如果objA , objB 皆为 值类型,则在 objA == objB 这一步骤无论如何都要得到一个false ,理由同前,因为它们要被装箱。实验如下:

int ia = 5;
int ib = 5;

object oa = ia; //这儿手动装下箱。
object ob = ib;

Console.WriteLine(oa == ob); // 结果是 false!!!

这时候后备的半句就用上了,

首先用 objA != null && objB != null 确保两个参数皆不为null ,然后调用了值类型本身的Equals 方法,这时候要明白,所有的值类型都继承自 System.ValueType 类,而ValueType 类复写了

public virtual bool Equals(Object obj);

方法,此时的Equals(Object obj)就可以进行值类型的恒等判断了,比较的是里面存放的内容,而非引用,这时候就能得到正确的结果了。验证如下:

int ia = 5;
int ib = 5;

object oa = ia;
object ob = ib;

Console.WriteLine(oa == ob); // 结果是 false!!!
Console.WriteLine(oa.Equals(ob)); // 结果是 true !!!!!

前面我们假设的是两个值类型的情况,可以正常满足判断功能。当两个参数皆为引用类型的时候,objA == objB 这前半个条件已经够用了。当两个参数一个为值类型一个为引用类型,那就显然不用说,也会得到false 啦。。。

最后还有一个virtual 的 Equals(object obj) 方法,当我们需要构建自定义的比较时,就需要重写该方法,它的默认实现是大多情况下并不实用的引用比较,当然System.ValueType已经复写了该方法。所以系统定义的那些值类型可以放心使用,它们会正常比较值的内容的。

下面部分转自:在路上

重写Equals方法分为以下三种情况:

1.引用类型的基类没有重写Equals

2.引用类型的基类重写了Equals

3.值类型重写了Equals

通常写法是:

对象是否为空,为空返回false

对象类型是否相同,不同返回false

类型转换后进行引用与值的比较如下:

Object.Equals(v1,v2) ,不同返回false

v1.Equals(v2),不同返回false

对于基类,if(!base.Equals(v2)) return false;

值类型可以自己实现强类型的Equals,避免拆箱与装箱操作.注意System.ValueType.Equals()利用了反射实现,效率不高.

注意:Object.ReferenceEquals();

重写Equals必须重写GetHashCode()
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐