https://www.cnblogs.com/ArtofDesign/p/3615212.html

 

C#中有一共有四种相等性判断方法:

//Object中定义的三个方法
public static bool ReferenceEquals(object objLeft, object objRight);
public static bool Equals(object objLeft, object objRight);
public virtual bool Equals(object obj); //双等号
public static bool operator == (MyClass left, MyClass right)

①Object.ReferenceEquals(left, right)静态方法:从名称中便可知它用来比较两者是否是相同的引用,我们也永远不应该去重写该方法。它对于值类型对象的比较永远返回false;对于两个null的比较永远返回true。

②Object.Equals(left, right)静态方法:该方法也永远不需要重写,因为它最终会把判断权交给参数left的实例Equls方法(代码如下),因此没有必要重写该方法,只需要保证实例Equals返回想要的结果即可:

public static bool Equals(object left, object right)
{
if(object.ReferenceEquals(left,right)) //如果引用相同,则必定相等(包含两个都是null的情况)
{
return true;
}
if(object.ReferenceEquals(left ,null)|| object.ReferenceEquals(null,right)) //若只有一个是null,则必定不等
{
return false;
}
return left.Equals(right);//两个都不是null,且也不是同一个引用,则根据left的实例Equals方法来判断。
}

③Object中的实例方法Equals,因为它是虚方法,所以可以在其他类中重写它。该方法的默认实现还是比较两者是否为同一个引用,即相当于ReferenceEquals。但是微软在所有值类型的基类System.ValueType中重写了该方法,用来比较值相等。

  • 在值类型中,我们仍然可能要重写该方法,以提高性能(默认方法的性能不高),另外如果我们的struct中包含了引用类型的成员,则应该重写该方法。
  • 在引用类型中,如果类的实例要作为字典的键,则应该重写Equals方法,使之比较值,而不是引用。

重写Equals应该遵循的原则:自反性、对称性、传递性。即:a=a;若a=b,则b=a;若a=b,b=c,则a=c;另外两个对象要么相等要不不等,所以该方法不应该抛出异常。下面是重写模板:

public class MyClass:IEquatable<MyClass>
{
//重写Object中的Equals方法
public override bool Equals(object obj)
{
if (object.ReferenceEquals(obj, null)) //首先判断obj不能为空,否则后面对obj调用任何方法都将报错
{
return false;
}
if(object.ReferenceEquals(this,obj)) //在C#中this永远不会为空
{
return true;
}
if(this.GetType() != obj.GetType())
{
return false;
}
return this.Equals(obj as MyClass);
}
//实现IEquatable<T>中的Equals方法
public bool Equals(MyClass other)
{
//省略
return true;
}
}

④比较运算符==:对于引用类型,默认是比较引用的(System.String除外),对于值类型默认比较值,对于自定义的结构,如果不显示重载operator ==方法,则无法使用==。

  • 由于在C#中要求比较运算符必须成对重载,重载==运算符的同时也必须重载!=运算符,否则也会产生编译错误。
  • 如果要重载的话,运算符"=="、"!="  与  Equals方法、GetHashCode方法应该同时被重载,因为他们应该保持同样的相等逻辑。但不要再==中调用Equals,最好是在Equals中调用==。

最新文章

  1. Scala Macros - scalamela 1.x,inline-meta annotations
  2. Openjudge 1.13-21:最大质因子序列(每日两水)
  3. 【原创】loadrunner12.53 录制脚本时 打不开网页或者打开网页慢?
  4. java高新技术-代理
  5. 当前主流的安卓APP开发IDE
  6. JAVA SSH 框架介绍
  7. android的helloworld工程目录学习
  8. apache开源项目 -- Tuscany
  9. matlab vs python
  10. 游戏音频技术备忘 (五)Wwise Unreal Engine 集成代码浅析 二
  11. 面试经验And总结
  12. Spring Cloud微服务笔记(五)Feign
  13. xpath | 计算两个节点集
  14. KONE-FLOW Vistor Key
  15. 20180821ImportContactFromExcel
  16. Delphi 10.3.1拍照遇到的问题
  17. 游戏编程模式KeyNote
  18. iOS.mach_absolute_time
  19. BZOJ4254 : Aerial Tramway
  20. JS如何遍历Object中的所有属性?

热门文章

  1. python判断文件后缀名
  2. JSON字符串需Aes加密,加密为Hex
  3. 常用的基础方法,对象转数组,phpcurl请求
  4. 初识swoole
  5. div 拖动 js实现
  6. 用CImage加载内存里的Image(转)
  7. git仓库搭建及免密使用
  8. CentOS7桥接网络设置(小白向)
  9. Markdowm的下载方法
  10. 20203412马畅若《Python程序设计》实验四Python综合实践报告