首页 新闻 会员 周边

在对象比较中,对象一致和对象相等分别是指什么?

0
悬赏园豆:5 [已关闭问题]
在对象比较中,对象一致和对象相等分别是指什么?
jerreychen的主页 jerreychen | 初学一级 | 园豆:185
提问于:2008-05-21 15:21
< >
分享
其他回答(4)
0
对象数据存内存堆里,对象一致即内存堆相同,对象相等为哈希表中键同值可能不同
yeyang | 园豆:418 (菜鸟二级) | 2008-05-21 16:35
1
你说的是相等性(equality)和同一性(identity)的区别吧? 简单的讲:相等性(quality)就是两个对象,它们的值相等。同一性(identity)就是指引用的是否为同一个对象。 下面是我的读书笔记: C# 中有两种不同的相等:引用相等和值相等。值相等是大家普遍理解的意义上的相等:它意味着两个对象包含相同的值。例如,两个值为 2 的整数具有值相等性。引用相等意味着要比较的不是两个对象,而是两个对象引用,这两个对象引用所引用的是同一个对象。我们这里把值相等叫做对象的“相等性(equality)”,把引用相等叫做对象的同一性(identity)。 我们都知道在System.Object类型中提供了一个名为Equals的虚方法,它的作用是在两个对象相等的情况下返回true,不相等时返回false。等等,这里的说的“相等”是哪个?是“相等性(equality)”还是“同一性(identity)”。好吧,来看一下代码吧,System的Object方法是像下面这样实现的: public class Object { public virtual Boolean Equals(Object obj) { // 如果两个引用指向的是同一个对象,那么它们肯定相等 if (this == obj) return true; // 假定对象不相等 return false; } } 表明上看它好像是实现的很合理:假如this和Obj引用同一对象,自然就是true了,因为Equals知道一个对象肯定等于它自身。然而,如果this和Obj引用不同的对象哪?,Equals就不能肯定对象是否包含相同的值,所以总结一句话就是:Object的Equals方法实现的只是“同一性(identity)”,而不是“相等性(equality)”。 多么的令人遗憾啊~!Object的Equals的默认实现并不合理,既然不合理我们就来重写它吧,先来看看如何在内部正确实现一个Equals方法(我把它概括为四个字——空、型、值、基): 如果obj参数为null,就返回false; 如果this和obj参数引用不同的类型对象,返回false; 针对类型定义的每个实例字段,将this对象的值和obj对象的值进行对比,任何字段不相等,就返回false; 调用基类的Equals方法,以便比较它定义的任何字段。如果基类的Equals方法返回false,就返回false;否则返回true; 再来看一下Object的Equals方法的实现代码: public class Object { public virtual Boolean Equals(Object obj) { if (obj == null) return false; if (this.GetType() != obj.GetType()) return false; // 如果对象属于相同的类型,那么在它们的多有字段都匹配的前提下返回true // 由于System.Object没有定义任何字段,所以字段是匹配的 return true; } } 其实,这里要说一下,Microsoft并没有这样去实现他的代码,而是要比这个复杂的多的多。 那么Equals方法可以在子类中重写,那么就不可以用Equals方法来测试同一性(identity)了。怎么办啊?Microsoft在Object中提供了一个静态方法ReferenceEquals,其原型如下: public class Object { public static Boolean ReferenceEquals(Object objA, object objB) { return (objA == objB); } } 注意了啊,如果想要检查同一性(identity),那么务必调用ReferenceEquals,而不应该使用C#的==操作符(除非事先把它们转化为Object类型),原因是其中某个操作数的类型可能重载了==操作符,为其赋予了其它语义。 另外,System.ValueType重写了Object的Equals方法。并进行了正确的实现来执行相等性(equality)检查,而不是同一性(identity)检查。在内部,ValueType的Equals方法是像这样实现的: 如果obj参数为null,返回false; 如果this和obj引用的不同类型的对象,返回false; 针对类型定义的每个实例字段,都将this对象的值和obj对象中的值进行比较。如果有字段不相等,就返回false; 返回true;ValueType的Equals的方法不会调用Object的Equals方法。 顺便说一下,ValueType的Equals方法是通过反射技术来完成的。由于CLR反射机制较慢,所以在定义自己的值类型时,应该重写Equals方法,并提供自己的实现,以便提高性能。当然在自己的实现中不要调用base.Equals。 要重写Equals,必须遵循一下几点特性: x.Equals(x) 返回 true。 (自反性) x.Equals(y) 与 y.Equals(x) 返回相同的值。 (对称性) 如果 (x.Equals(y) && y.Equals(z)) 返回 true,则 x.Equals(z) 返回 true。 (传递性) 只要不修改 x 和 y 所引用的对象,x.Equals(y) 的后续调用就返回相同的值。 (一致性) x.Equals(null) 返回 false。
啊不才 | 园豆:210 (菜鸟二级) | 2008-05-21 20:53
0
我也不太明白,看了楼上的,明白一点点了。复制下先
奇军 | 园豆:265 (菜鸟二级) | 2008-05-22 17:47
0
对象们都住在不同的房间里,每个房间只能住一个对象.对象们都被锁在房间里,永远没有办法搬家(至少从我们讨论的角度来说,这个说法是正确的).所以如果你知道了一个对象的房间号,就能找到对应的对象. 现在假如我们有两张名片,上面如果写着相同的房间号,我们就可以断定,这两张名片是同一个对象分发出来的,这就是同一性,也就是你所说的一致. 假如1号房里住着一个值为1的整数对象, 2号房里住着另一个值为2的整数对象,3号房里住着另另一个值为1的整数对象.我们又有它们各自的一张名片, 那么,第一个名片和第三个对应的对象的值是相等的,但是它们不是同一个对象,用你的词来说,也就是说它们"相等",但不"一致". 如果上面说得太清楚了,那么这里让你再困扰一会吧,哈哈: 这里的名片就是引用(i, count之类的变量/字段等的名称); 房间所在的大楼就是内存,房间号就是内存地址. 对象就是内存里保存的数据.
deerchao | 园豆:8367 (大侠五级) | 2008-05-23 00:21
0
同一个对象 和 对象内容相同
Animax! | 园豆:315 (菜鸟二级) | 2008-05-23 20:45
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册