C# - 重写比较

C# Equals 和 ReferenceEquals 使用详解 阅读详情

原文:http://msdn.microsoft.com/zh-cn/library/ms173147.aspx


重写Equals

由于 Equals 是一个虚方法,因此任何类都可以重写其实现。表示某个值(本质上可以是任何值类型)或一组值(如复数类)的任何类都应该重写 Equals。如果类型要实现 IComparable,则它应该重写 Equals。

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(仅非空值类型。有关更多信息,请参见可空类型(C# 编程指南)。)

Equals 的新实现不应该引发异常。建议重写 Equals 的任何类同时也重写 Object.GetHashCode。除了实现 Equals(对象)外,还建议所有的类为自己的类型实现 Equals(类型)以增强性能。例如:

C#
class TwoDPoint : System.Object
{
    public readonly int x, y;

    public TwoDPoint(int x, int y)  //constructor
    {
        this.x = x;
        this.y = y;
    }

    public override bool Equals(System.Object obj)
    {
        // If parameter is null return false.
        if (obj == null)
        {
            return false;
        }

        // If parameter cannot be cast to Point return false.
        TwoDPoint p = obj as TwoDPoint;
        if ((System.Object)p == null)
        {
            return false;
        }

        // Return true if the fields match:
        return (x == p.x) && (y == p.y);
    }

    public bool Equals(TwoDPoint p)
    {
        // If parameter is null return false:
        if ((object)p == null)
        {
            return false;
        }

        // Return true if the fields match:
        return (x == p.x) && (y == p.y);
    }

    public override int GetHashCode()
    {
        return x ^ y;
    }
}


可调用基类的 Equals 的任何派生类在完成其比较之前都应该这样做。在下面的示例中,Equals 调用基类 Equals,后者将检查空参数并将参数的类型与派生类的类型做比较。这样就把检查派生类中声明的新数据字段的任务留给了派生类中的 Equals 实现:

C#
class ThreeDPoint : TwoDPoint
{
    public readonly int z;

    public ThreeDPoint(int x, int y, int z)
        : base(x, y)
    {
        this.z = z;
    }

    public override bool Equals(System.Object obj)
    {
        // If parameter cannot be cast to ThreeDPoint return false:
        ThreeDPoint p = obj as ThreeDPoint;
        if ((object)p == null)
        {
            return false;
        }

        // Return true if the fields match:
        return base.Equals(obj) && z == p.z;
    }

    public bool Equals(ThreeDPoint p)
    {
        // Return true if the fields match:
        return base.Equals((TwoDPoint)p) && z == p.z;
    }

    public override int GetHashCode()
    {
        return base.GetHashCode() ^ z;
    }
}

重写==

默认情况下,运算符 == 通过判断两个引用是否指示同一对象来测试引用是否相等。因此引用类型不需要实现运算符 == 就能获得此功能。当类型不可变(即实例中包含的数据不可更改)时,通过重载运算符 == 来比较值是否相等而不是比较引用是否相等可能会很有用,因为作为不可变的对象,只要其值相同,就可以将其视为相同。建议不要在非不可变类型中重写运算符 ==。

重载的运算符 == 实现不应引发异常。重载运算符 == 的任何类型还应重载运算符 !=。例如:

C#
//add this code to class ThreeDPoint as defined previously
//
public static bool operator ==(ThreeDPoint a, ThreeDPoint b)
{
    // If both are null, or both are same instance, return true.
    if (System.Object.ReferenceEquals(a, b))
    {
        return true;
    }

    // If one is null, but not both, return false.
    if (((object)a == null) || ((object)b == null))
    {
        return false;
    }

    // Return true if the fields match:
    return a.x == b.x && a.y == b.y && a.z == b.z;
}

public static bool operator !=(ThreeDPoint a, ThreeDPoint b)
{
    return !(a == b);
}






C#中重写包含子类集合的类的Equals方法 现在,我们希望创建一个名为EmployeeCollection的类,它包含多个Employee对象,并重写Equals方法以比较两个EmployeeCollection对象的内容是否相等。在C#中,当我们定义一个包含子类集合的类时,为了实现正确的相等性比较,我们需要重写Equals方法。在上面的示例中,我们创建了三个EmployeeCollection对象,其中两个对象(collection1和collection2)具有相同的集合内容,而第三个对象(collection3)具有不同的集合内容。 阅读详情

相关推荐

echarts 生成中国陕西省份(或其他省份)的地图,大屏使用

效果图: 一、首先第一步需要下载echarts和获取到陕西身份的地图信息。 1.下载echarts链接(官网): Apache ECharts 2.生成指定省份的地图数据信息,数据可以在阿里云获取。 DataV.GeoAtlas地理小工具系列 如图,点击左圈需要的省份,这里我选择的是陕西省,然后点击右圈复制下载链接,得到一个json格式的数据,可以在json转换网站转成js格式。 Json在线解析格式化-Json在线校验Json格式化压缩-Jsons在线工具 转成js格.

PrimaryColor 3890

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

问题: 写单元测试时,需要对比两个对象是否相等,如果使用Assert.AreEqual(mockclass1, class1)永远无法通过。 原因: 这里使用了object默认的Equals方法,必须要引用同一个对象,才会返回true 。默认的Equals方法实现的只是同一性(identity),而不是相等性(equality)。 合理的Equals方法本应该这样实现: 如果obj实参为空,就返...

两个轮子的博客 7502

如何通过常规测井曲线识别砂岩、泥岩、碳酸盐岩和煤层

常规测井曲线通过不同岩性的物理性质差异识别砂岩、泥岩、碳酸盐岩和煤层。砂岩表现为低自然伽马(GR)、中等密度(RHOB)和声波时差(DT);泥岩以高GR、高中子(NPHI)和高DT为特征;碳酸盐岩显示低GR、高RHOB和低DT;煤层则具有极低RHOB、极高NPHI和DT的独特组合。综合GR与三孔隙度曲线(RHOB、NPHI、DT)可有效区分岩性,其中密度测井对煤层识别最可靠。电阻率(RT)曲线辅助判断流体性质,但需结合其他参数综合分析。

love code, love life. 2593

C# 重写IComparer 接口

首先定义比较类 继承自IComparer<Racer> 1 public class RacerComparer : IComparer<Racer> 2 { 3 public enum CompareType 4 { 5 FirstName, LastName, Coun...

dianzhuique8587的博客 481

发票OFD格式转换成PDF

发票OFD格式转换成PDF

Be_insighted的博客 933

AD23导出Gerber文件保姆级教程:从PCB到嘉立创下单,一步不落(附常见问题排查)

本文提供AD23导出Gerber文件的详细教程,涵盖从PCB设计检查到嘉立创下单的全流程,特别针对两层板设计场景,帮助新手工程师避免常见错误。内容包括Gerber文件生成步骤、钻孔文件设置、文件检查工具推荐以及嘉立创下单实操指南,确保PCB打样顺利。

weixin_30924239的博客 440

C#比较类的大小

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Collections; namespace practise_1 { class Program { class Person:IComparable { public

木辛木又 839

西门子840D新建项目

1、需要一个32位的WIN7或者XP系统,并且已经在系统中安装完成西门子840Dsl开发包和VS2008。(我采用的是XP系统虚拟机) 2、在开始->所有程序找到如下位置 3、在这个位置打开Visual Studio 4、文件->新建->项目 名称和位置都可以随意更改,点击确定。 5、在左侧选择第二个选项进入下面的界面 点击“Add Screen”按钮 可以修改“class name”然后点击“OK”返回上一个界面,再点击“Add Form” 可以修...

qq_36987047的博客 1861

重写CompareTo

CompareTo( Object o ) compare默认被当前对象调用,比较属性时可以用this.调用,而这个参数 Object o 代表前一个对象。当向Set集合中新添加一个元素的时候,这个元素会和之前集合里面的所有元素进行比较,从而选择插入的位置。 compareTo方法的返回值是int类型,例如,当” this.属性 - o.属性 “ 返回一个正数,表示this比o大,把this排在o后面。 返回负数相反。 返回0,表示无所谓。 以下的例子,把Teacher类的对象先按...

qq_39484718的博客 3498

✨在Windows11上安装虚拟机(VMware17.6.0)保姆级教程(附安装包)

VMware Workstation Pro 是一款功能强大的虚拟机软件,它允许你在单一的物理机上运行多个操作系统。性能卓越:VMware以其出色的性能和稳定性而闻名,适合运行资源密集型的虚拟机。用户友好:直观的用户界面使得即使是初学者也能快速上手。功能全面:支持多种操作系统,包括Windows、Linux、macOS等,满足不同用户的需求。企业级支持:VMware提供全面的技术支持,适合企业级用户。恭喜你成功安装了VMware Workstation Pro 17.6.0!

Python老吕的博客 1万+

starrc: LEF DEF FLOW与full chip flat netlist

SIKP_CELLS默认为"SKIP_CELLS: *"意思是跳过所有ref cell内部的rc提取,仅提取cell之间的互联线的rc,"SKIP_CELLS: *!与MACRO_DEF_FILE搭配使用的还有SKIP_CELLS命令,如果想提取block的寄生参数生成full chip的flat netlist,或者跳过block取执行hier的寄生参数提取都需要用到SKIP_CELLS。此时,macroA和macroB没有被跳过,所以提取其内部的rc,spef中存在两个A和两个B。

m0_61544122的博客 553

C#重写Equals()

今天在乐扣做题遇见这个问题 感觉没有总结过 记录一下 C#中Equals和= =(等于号)的比较) 相信很多人都搞不清Equals和 = =的区别,只是零星的懂一点,现在就让我带大家来进行一些剖析 一、 值类型的比较 对于值类型来说 两者比较的都是”内容”是否相同,即 值 是否一样,很显然此时两者是划等号的。 例: int i = 9; int j = 9; Console.WriteLine("Equals和= =(等于号)的比较");

qq_27636823的博客 1528

可食用野生植物检测实战:基于YOLOv11的智能识别系统全流程指南

本文介绍了一种基于YOLOv11的可食用野生植物智能识别系统。该系统通过深度学习技术,能在0.2秒内精准识别植物是否可食用,准确率高达92%。文章详细阐述了从数据采集、标注到模型训练、验证的全流程,并开发了用户友好的Tkinter交互界面。该系统解决了户外探险和植物研究中植物识别的痛点,具有高精度、实时性和强泛化能力的特点,为户外安全提供了智能化解决方案。

FJN110的博客 164

C#中在比较自定义对象的时候要重写Equals方法

using System;using System.Collections.Generic;using System.Text; namespace Equal{using System; class Test{public static void Main(){Person p1 = new Person("A"...

weixin_30306905的博客 247

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

你真的会重写Equals吗?:C#结构体比较的底层机制全曝光

掌握C#结构体的Equals重写技巧,解决值类型比较难题。详解IEquatable接口实现、哈希一致性处理及性能优化要点,适用于高频比较场景。理解底层机制,提升代码效率,值得收藏。

ProceChat的博客 638

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

让我们来比较C#,C++和Java之间重写虚函数的区别

让我们来比较C#,C++和Java之间重写虚函数的区别

IT1995的博客 5081

C#(二十五)之C#对象比较

(一):比较对象的方法 概念有点多,看看就行了: 1:ReferenceEquals: Object.ReferenceEquals(left, right)静态方法:从名称中便可知它用来比较两者是否是相同的引用,我们也永远不应该去重写该方法。它对于值类型对象的比较永远返回false;对于两个null的比较永远返回true。此方法必须使用类来调用。 cat f1 = new cat(5); cat f2 = new cat(5); // ReferenceEquals Console.WriteLine("

camellia的博客 2090

c# 两个list比较_C# 两个List<T>(T是类)使用Contains比较元素的方法

众所周知,List创建的对象是引用类型,也就是说,两个完全相同的List对象(其中元素及其元素的属性也相同),但引用地址不同,在使用Contains判断两List中元素包含比较时,返回都是False,因此,我们需要重新“定义”Contains,实际上,Contains内部是Equals方法的封装,所以,我们需要重写Equals方法: 1 public class UserInfo : ...

weixin_39637151的博客 1860

C#中匿名类型的相等性比较陷阱(Equals重写机制大揭秘)

揭秘C#匿名类型相等性比较陷阱,深入解析C#匿名类型的Equals重写机制。涵盖编译器自动生成的Equals、GetHashCode实现原理,适用于集合去重、对象比较等场景,确保类型安全与性能兼备。理解底层逻辑,避免常见误区,值得收藏。

ProceChat的博客 582

C#比较

C#是如何比较的,首先看如下程序,p1和p2是两个不同的引用,所以第一次比较输出no same。 p1和p3引用同一段内存空间,所以第二次比较输出same。 class Program { static void Main(string[] args) { person p1 = new person { name = "SLH" }; person p2 = new person { name = "SLH...

SLRiver的博客 486

关于C#类中重写ToString方法和PHP类中__tostring()方法的比较

今天在复习C#的时候遇到在类中override(重写)ToString()方法的情况,这其实是一个比较好用的办法,我们不用调用任何方法,就可以直接访问到我类中的我设定的面向大众的一些类信息。代码如下://定义一个动物类 public class CAnimal { public int age; public double weight; pu

LSGOZJ的博客 1097

C#结构体Equals重写实战指南(避免装箱的高效实现方案)

掌握C#结构体的Equals重写技巧,避免装箱提升性能。适用于高频比较场景,通过重写Equals和GetHashCode实现高效值语义判断,减少内存开销。核心方法清晰实用,值得收藏。

LiteTrans的博客 1063

【C#XML】C#重写Equals方法,用于比较XML提取的用户信息

1、创建一个实体类 { public int Id { set; get; } public string Name { set; get; } public int Age { set; get; } public char Gender { set; get; } **//重写Equals方法** public override bool Equ...

qq_19660269的博客 224

C# Equals的重写

来自:http://blog.sina.com.cn/s/blog_4baa3af301000a1e.html using System; using System.Collections.Generic; using System.Text; namespace Equal {     using System;     class Test     {  

码农 1992

[C#]简单重写IComparer接口,实现自己的String.CompareTo 方法,自定义比较规则。

在项目中经常会用到字符串比较,但是有时候对字符串的操作比较多,规则各异。 比如有的地方我们需要用排序规则,有的地方需要忽略大小写,我们该如何写一个比较容易操作的比较方法呢? 重新实现IComparer接口不失为一个好办法。 我们可以在实现Compare方法的时候指定比较规则CompareOptions 成员名称 说明 IgnoreCase 指示字符串比较必须忽

Hauk.Wong 7834

四种C#对象的比较方式

(为了获取最佳性能,hash函数为对象内容生成的数字是随机分布的,这就意味着,内容不同的对象,有可能生成的数字是一样的,但可以认为这种概率非常小)。这样一来,string类型虽然是引用类型,但是其==操作和Equals操作都是一样的,均比较值是否相等。对于引用类型而言,其栈中存储的是对象的地址,那么==就是比较两个地址是否相等,即是否指向同一个对象;值类型存储在栈上,故用==判断是直接判断其值是否相等,因为值类型不存在堆中的数据,因此值类型的Equals也是判断数据。若a=b,b=c,则a=c;

学习之路,创业之光 756
上一篇: 自动化测试 - 单元测试
下一篇: 经典软件设计模型 - MVC
G机器猫
博客等级 码龄16年 106粉丝 74原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值