【C#】如何比较两个对象是否相等(重写Equals方法)

2023-11-06

问题: 写单元测试时,需要对比两个对象是否相等,如果使用Assert.AreEqual(mockclass1, class1)永远无法通过。

原因: 这里使用了object默认的Equals方法,必须要引用同一个对象,才会返回true 。默认的Equals方法实现的只是同一性(identity),而不是相等性(equality)

合理的Equals方法本应该这样实现:

  1. 如果obj实参为空,就返回false,因为调用的是非静态Equals方法,this标识的当前对象肯定不为空;
  2. 如果thisobj实参引用同一个对象,就返回true。在比较大量字段时,这一步有助于提升性能;
  3. 如果thisobj实参引用不同类型的对象,就返回false
  4. 针对类型定义的每个实例字段,将this对象中的值与obj对象中的值进行比较,任何字段不相等,返回false
  5. 调用基类的Equals方法比较它定义的任何字段,返回基类的Equals结果。

由于Microsoft并没有这样实现Equals,所以需要针对不同的对象重写Equals方法,为了仍然能测试同一性,Object提供了静态方法ReferenceEquals

同一性

检查同一性(看两个引用是否指向同一个对象),务必调用 ReferenceEquals,不应该使用==操作符,因为类型可能重载了操作符。

相等性

重写Equals方法时,除了上文所讲的,还应该做下面几件事:

  • 让类型实现System.IEquatable<T>接口的Equals方法。
    这个泛型接口允许定义类型安全的Equals方法,在重写的Equals(object obj)方法中调用这个类型安全的方法。
  • 重载==!=操作符方法。
  • 如果需要排序而比较类型的实例,还应该实现System.IComparableCompareTo方法以及各种比较操作符。
  • 重写类型的GetHashCode方法。
    由于在System.Collections.HashtableSystem.Collections.Generic.Dictionary以及其他一些集合的实现中,要求两个对象必须具有相同的哈希码才被视为相等。

具体例子如下,完整可参考 MSDN IEquatable.Equals(T) Method

public class Person : IEquatable<Person>
{
    private string _name;
    private string _id;

    public Person(string name, string id)
    {
        _name = name;
        _id = id;
    }

    public string Name
    {
        get { return _name; }
        set { _name = value; }
    }

    public string Id
    {
        get{ return _id; }
        set{ _id = value; }
    }

    //自定义的Equals方法
    public bool Equals(Person other)
    {
        if (other == null) return false;

        if (_name == other.Name && _id == other.Id)
            return true;
        else
            return false;
    }
    //重写基类中的Equals方法
    public override bool Equals(object obj)
    {
        if (obj == null) return false;

        Person personObj = obj as Person;
        if (personObj == null)
            return false;
        else
            return Equals(personObj);
    }
    
    public override int GetHashCode()
    {
        return _name.GetHashCode() ^ _id.GetHashCode();
    }
}

拓展阅读:
https://www.cnblogs.com/yang_sy/archive/2014/03/07/3582946.html

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【C#】如何比较两个对象是否相等(重写Equals方法) 的相关文章

随机推荐

  • 数据结构(1)前言

    1 学习数据结构前 需要掌握结构体和指针的使用 需要了解typedef这个关键字 对这部分知识欠缺的可以查看 C语言结构体详解 何为指针 与数组名有什么区别 2 作为一名想成为嵌入式软件工程师的人而言 很多像电气工程 电子信息等专业的人在大
  • Windows11 文件选择打开方式时卡死 解决

    发生的现象 在 打开方式 窗口的地址栏粘贴应用的地址 gt 打开方式界面卡死 完整步骤 左键点击打开epub文件 gt 跳出 寻找一个应用以打开此 epub文件 gt 选择 在电脑上选择应用 gt 弹出 打开方式 窗口 gt 在 打开方式
  • ❤ 15个基于Vue3.0全家桶的优秀开源项目

    15个基于Vue3 0全家桶的优秀开源项目 Vue Admin Better github https github com chuzhixin vue admin better vue admin better 对比其他来源 admin
  • 雨停了,我将雨伞收起

    天空中已有阳光从厚重的云层间隙射向大地 我将手中的雨伞收起 伞面上留存着的雨滴正沿着伞面的褶皱流下打在地上 我望向远方 一辆汽车沿着自己的轨迹行驶 路边小坑中的积水在车轮的驱赶下纷纷跳上灌木丛的绿叶寻找庇护 一阵清脆的自行车铃在身后响起 一
  • Android BaseQuickAdapter万能适配器

    RecycleView万能适配器 一导入 implementation com github CymChad BaseRecyclerViewAdapterHelper 2 9 24 implementation com android s
  • spring-kafka并行度concurrency在应用集群部署(多个节点)正确设置,附上Kafka Manager监控效果

    我们都知道kafka有topic的概念 为了能够更好的支持水平扩容 topic又分了很多的Partition 消费者负责消费Partition中的消息 一个Partition只能被一个消费者消费 但是一个消费者可以消费多个partition
  • zotero与Obsidian联动笔记(二):zotero拖拽highlights的格式修改

    文章目录 zotero拖拽highlights的格式修改 zotero拖拽highlights的格式修改 方法 两种格式的文本 p highlight quotes true citation comment p blockquote hi
  • unity 3D RPG教程(一)

    目录 声明 1 Create Project 2 Build Level 3 PolyBrush 发挥创意构建场景 4 Navigation 智能导航地图烘焙 5 MouseManager 鼠标控制人物移动 声明 本教程学习均来自U3D中文
  • mysql中ddl语句有哪些_什么是 DDL 语言?其中包括哪些语句?

    展开全部 DDL一般指数据定义语32313133353236313431303231363533e4b893e5b19e31333431373937言 数据库模式定义语言DDL Data Definition Language 是用于描述数
  • 华为OD机试 - 跳格子游戏(Java)

    题目描述 地上共有N个格子 你需要跳完地上所有的格子 但是格子间是有强依赖关系的 跳完前一个格子后 后续的格子才会被开启 格子间的依赖关系由多组steps数组给出 steps 0 表示前一个格子 steps 1 表示steps 0 可以开启
  • C++(14):函数返回类型auto推导

    C 11可以通过结合auto和decltype来动态的声明函数的返回值类型 include
  • plt.style.use设置背景样式

    利用matplotlib绘图设置背景 使用到plt style use 时 对这个参数做一下小结 matplotlib 使用某种样式 plt style use 参数可以是一个 URL 或者路径 指向自己定义的 mplstyle 文件 可以
  • 翁凯c语言作业8-3

    include
  • Vue初始化在HBuilderx中快速搭建

    HBuilderx快速新建VUE项目 一 安装HBuilderx开发工具 官网 HBuilderx HBuilderXH是HTML的第一个字母 Builder是builder X是HBuilder的下一个版本 我们也被称为HX HBuild
  • 01.minio基本介绍搭建使用

    MinIO 是一款基于 Go 语言的高性能 可扩展 云原生支持 操作简单 开源的分布式对象存储产品 官网 https min io 特点 高性能 作为高性能对象存储 在标准硬件条件下它能达到55GB s的读 35GG s的写速率 可扩容 不
  • 随机生成6位随机数(字母+数字)

    package com test public class test public static void main String args String randomcode 用字符数组的方式随机 String model 0123456
  • 人生应该接受的教育

    以下三段话 或许会让你的人生发生一些变化 如果有心改变 一切都不晚 一 比尔 盖茨告诉我们 1 社会充满不公平现象 你先不要想去改造它 只能先适应它 因为你管不了它 2 世界不会在意你的自尊 人们看的只是你的成就 在你没有成就以前 切勿过分
  • openssl基本原理及生成证书

    openssl基本原理及生成证书 openssl基本原理及生成证书 1 基本原理 2 生成证书 一 生成CA证书 1 创建私钥 2 创建证书请求 3 自签署证书 4 将证书导出成浏览器支持的 p12格式 二 生成server证书 1 创建私
  • 6套粒子群算法(内含matlab代码)

    粒子群算法 1 粒子群算法简介 一 粒子群算法的历史 粒子群算法源于复杂适应系统 Complex Adaptive System CAS CAS理论于1994年正式提出 CAS中的成员称为主体 比如研究鸟群系统 每个鸟在这个系统中就称为主体
  • 【C#】如何比较两个对象是否相等(重写Equals方法)

    问题 写单元测试时 需要对比两个对象是否相等 如果使用Assert AreEqual mockclass1 class1 永远无法通过 原因 这里使用了object默认的Equals方法 必须要引用同一个对象 才会返回true 默认的Equ