关于 warning CS0659:“***”重写Object.Equals(object o)但不重写Object.GetHashCode()
对象相等性和同一性
- System.Object 类型提供了以下方法,
namespace System
{
//
// 摘要:
// 支持 .NET Framework 类层次结构中的所有类,并为派生类提供低级别服务。这是 .NET Framework 中所有类的最终基类;它是类型层次结构的根。
[ClassInterface(ClassInterfaceType.AutoDual)]
[ComVisible(true)]
public class Object
{
//
// 摘要:
// 初始化 System.Object 类的新实例。
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
public Object(); //
// 摘要:
// 允许对象在“垃圾回收”回收之前尝试释放资源并执行其他清理操作。
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
~Object(); //
// 摘要:
// 确定指定的对象实例是否被视为相等。
//
// 参数:
// objA:
// 要比较的第一个对象。
//
// objB:
// 要比较的第二个对象。
//
// 返回结果:
// 如果认为对象相等,则为 true;否则为 false。如果 objA 和 objB 都为 null,则方法返回 true。
[TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")]
public static bool Equals(Object objA, Object objB);
//
// 摘要:
// 确定指定的 System.Object 实例是否是相同的实例。
//
// 参数:
// objA:
// 要比较的第一个对象。
//
// objB:
// 要比较的第二个对象。
//
// 返回结果:
// 如果 objA 是与 objB 相同的实例,或如果两者均为 null,则为 true;否则,为 false。
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
[TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")]
public static bool ReferenceEquals(Object objA, Object objB);
//
// 摘要:
// 确定指定的对象是否等于当前对象。
//
// 参数:
// obj:
// 要与当前对象进行比较的对象。
//
// 返回结果:
// 如果指定的对象等于当前对象,则为 true;否则为 false。
[TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")]
public virtual bool Equals(Object obj);
//
// 摘要:
// 作为默认哈希函数。
//
// 返回结果:
// 当前对象的哈希代码。
[TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")]
public virtual int GetHashCode();
//
// 摘要:
// 获取当前实例的 System.Type。
//
// 返回结果:
// 当前实例的准确运行时类型。
[SecuritySafeCritical]
public Type GetType();
//
// 摘要:
// 返回表示当前对象的字符串。
//
// 返回结果:
// 表示当前对象的字符串。
public virtual string ToString();
//
// 摘要:
// 创建当前 System.Object 的浅表副本。
//
// 返回结果:
// 当前 System.Object 的浅表副本。
[SecuritySafeCritical]
protected Object MemberwiseClone();
}
}Syste.Object
- 其中提供了名为Equals的虚方法,它的作用是在两个对象相等的前提下返回true.
- Equals方法初实现
看起来似乎是合理的实现,但问题是如果实参引用不同的对象,Equals就不能判断对象是否包含相同的值,就会判定为False.对于Object的Equals的默认实现,它实现的是同一性,而非相等性。
- 针对以下问题,1)obj实参是否为null,2)this和obj实参是否是引用同一个对象,3)this和obj实参是否引用不同类型的对象,实现Object的Equals方法。
public class Object
{
public virtual Boolean Equals(Object obj)
{
if (obj == null)
return false;
if (this.GetType() != obj.GetType())
return false; return true; ;
}
}Equals方法
- 一个类型重写Equals方法时,重写的方法应调用基类的Equals实现(除非这个基类就是Object).另外一个类型能重写Object的Equals方法,所以不能在调用这个Equals方法来测试同一性。Object提供了一个静态方法ReferenceEquals,其原型如下:
public Boolean ReferenceEquals(Object objA, Object objB)
{
return (objA == objB);
}ReferenceEquals
如果想检查同一性(看两个引用是否指向同一个对象),那么务必调用ReferenceEquals,而不应使用C#的==操作符(除非先把两个操作数都转型为Object)
- ValueType的Equals方法使用反射技术,由于CLR的反射机制较慢,所以在定义自己的值类型时,应该重写Equals方法,提供自己的实现,以便在用类型的实例进行值的相等性比较时提高性能。当然,在自己的视线中,不要调用base.Equals。
- 定义自己的类型时,如果决定重写Equals,必须确定它符合相等性的4个特征。
- 1)Equals必须是自反的。
- 2)Equals必须是对称的。
- 3)Equals必须是可传递的。
- 4)Equals必须是一致的。
- 重写Equals方法,还要:
- 让类型实现System.IEquatable<T>接口的Equals方法。这个泛型接口允许你定义一个类型安全的Equals方法。
- 重载==和!=操作符方法 通常应事先这些操作符方法,在内部调用类型安全的Equals方法.
除此之外,假如以后出于排序的目的而比较类型的实例,那么类型华英实现System.IComparable的CompareTo方法和System.IComparable<T>的CompareTo方法。
对象哈希吗
System.Object提供了虚方法GetHashCode,它能获取任意对象的Int32哈希吗。
- 如果定义的一个类型重写了Equals方法,那么还应重写GetHashCode()方法。如果定义的类型在重写Equals的同时没有重写GetHashCode(),Microsoft的C#编译器会报告一条警告消息,例如以下类型,会显示警告消息:warning CS0659:“Program”重写Object.Equals(object o)但不重写Object.HetHashCode().
- 重写Equals
之所以要同时定义GetHashCode,是因为在System.Collections.Hashtable类型、System.Collections.Generic.Dictionary类型以及其他一些集合的实现中,要求两个对象为了相等,必须具有相同的哈希吗,所以,如果重写了Equals,那么还应重写GetHashCode,确保相等性算法和对象哈希吗算法是一致的。
internal sealed class Point
{
private Int32 m_x, m_y;
public override int GetHashCode()
{
return m_x ^ m_y;
}
}GetHashCode
关于 warning CS0659:“***”重写Object.Equals(object o)但不重写Object.GetHashCode()的更多相关文章
- 你不知道的东西! c# == 等于运算符 和 Object.Equals()
最近在看 高级点的程序员必看的 CLR via C# 书中说解释了 Object.Equals() 方法的实现, 其中具体的实现用的是 == 运算符 ! 以前就对 == 运算符 的具体 ...
- 讲的很详细的一篇关于object equals() & hashCode() 的文章
转: 讲的很详细的一篇关于object equals() & hashCode() 的文章 哈希表这个数据结构想必大多数人都不陌生,而且在很多地方都会利用到hash表来提高查找效率.在Java ...
- 【Java编码准则】の #11不要使用Object.equals()来比較密钥值
java.lang.Object.equals()函数默认情况下是不能用来比較组合对象的,比如密钥值.非常多Key类没有覆写equals()函数,因此,组合对象的比較必须单独比較里面的各个类型以保证正 ...
- Java中Object.equals和String.equals的区别详解
前言 Java中的堆和常量池的区别是什么呢?Object.equals与String.equals的区别呢?下面让我们通过一个小示例让你明白它- 1.基础知识 Java的存储空间:寄存器.栈.堆.静态 ...
- object.Equals与object.ReferenceEquals方法
object.Equals方法表达的是语义判等,不一定是引用判等. object.ReferenceEquals方法是肯定是引用判等. 怎么实现一个对象的值语义的 Equals方法?实验. MyCla ...
- java中equals方法和hashcode方法的区别和联系,以及为什么要重写这两个方法,不重写会怎样
一.在Object类中的定义为:public native int hashCode();是一个本地方法,返回的对象的地址值.但是,同样的思路,在String等封装类中对此方法进行了重写.方法调用得到 ...
- JAVA中重写equals()方法的同时要重写hashcode()方法
object对象中的 public boolean equals(Object obj),对于任何非空引用值 x 和 y,当且仅当 x 和 y 引用同一个对象时,此方法才返回 true:注意:当此方法 ...
- 为什么重写了equals() 就要重写hashcode()
规定:1.两个对象相等,则hashcode也一定是相等的:2.两个对象相等,对两个对象分别调用equals()都返回 true:3.两个对象有相同的hashcode,但不一定相等 为什么重写了equa ...
- Java中Set的contains()方法——hashCode与equals方法的约定及重写原则
转自:http://blog.csdn.net/renfufei/article/details/14163329 翻译人员: 铁锚 翻译时间: 2013年11月5日 原文链接: Java hashC ...
随机推荐
- 在IIS上搭建FTP站点
操作环境 系统:win7 IIS版本:7.5 FTP传输工具:FlashXP 概述 本文介绍了如何在win7下利用IIS(默认已安装IIS和FTP功能)搭建FTP站点,FTP站点的常用配置. 快速搭建 ...
- PCA最小平方误差理论推导
PCA最小平方误差理论推导 PCA求解其实是寻找最佳投影方向,即多个方向的标准正交基构成一个超平面. 理论思想:在高维空间中,我们实际上是要找到一个d维超平面,使得数据点到这个超平面的距离平方和最小 ...
- div横排放置对齐问题;block,inline,inline-block区别
1.左右两个div都设置为float:left,如果右边div没有设置宽度,右边div的宽度会根据div里的内容自动调整. 缺点:不易控制 2.只有左侧div设置为float:left,右侧div设置 ...
- RUAL1519 Formula 1 【插头DP】
RUAL1519 Formula 1 Background Regardless of the fact, that Vologda could not get rights to hold the ...
- 20179223《Linux内核原理与分析》第二周学习笔记
第二周实验 本周学习情况: 学习了X86 cpu的几个寄存器及X86汇编指令: movl %eax,%edx edx=eax %表示一个寄存器,把eax内容放入edx,等号相当于把eax赋值给edx, ...
- java和c++中的DES\3DES\Base64
首先来看一段java中对字符串加解密的代码: //密钥 private String key = "123456789012345678901234"; //解密过程,先用Base ...
- java中如何高效的判断数组中是否包含某个元素---
package zaLearnpackage; import org.apache.commons.lang3.ArrayUtils; import java.util.Arrays; import ...
- 【DUBBO】zookeeper在dubbo中作为注册中心的原理结构
[一]原理图 [二]原理图解释 流程:1.服务提供者启动时向/dubbo/com.foo.BarService/providers目录下写入URL2.服务消费者启动时订阅/dubbo/com.foo. ...
- 解压RPM包
有时我们需要RPM包中的某个文件,如何解压RPM包呢? RPM包是使用cpio格式打包的,因此可以先转成cpio然后解压,如下所示: rpm2cpio xxx.rpm | cpio -div 例如: ...
- ibernate+Struts2环境如何使用jqGrid。
因为公司项目需要,在Hibernate+Struts2的环境下,研究了一下如何使用jqGrid. 说实在的,Struts2+jqGrid不是一个很好的组合.因为jqGrid中很多功能,基本上都使用的是 ...