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)具有不同的集合内容。 阅读详情

相关推荐

【水文】calico-node 启动失败 Init:CrashLoopBackOff

Defaulted container "calico-node" out of: calico-node, upgrade-ipam (init), install-cni (init), mount-bpffs (init) Error from server (BadRequest): container "calico-node" in pod "calico-node-4j7td" is waiting to start: PodInitializing

大健的日常的博客 1万+

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

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

两个轮子的博客 7502

国产麒麟系统各版本镜像下载

以上各链接均为迅雷下载,禁止商业用途!

2302_79474754的博客 6135

C# 重写IComparer 接口

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

dianzhuique8587的博客 481

别再死记硬背菜单了!用Workbench搞定你的第一个ANSYS结构分析(附模型文件)

本文为零基础用户提供使用ANSYS Workbench完成第一个结构分析的完整指南。通过悬臂梁案例详细讲解从几何导入、材料定义、网格划分到边界条件设置的全流程,帮助初学者快速掌握有限元分析的基本操作,并附赠实用模型文件。

weixin_34233974的博客 307

SAP_ABAP_MM_BAPI清单案例教程——采购发票校验/预制_BAPI_INCOMINGINVOICE_PARK_MIRO

SAP ABAP BAPI_INCOMINGINVOICE_PARK BAPI 采购发票预制 采购发票校验 代码模版

java_zhong1990的专栏 1963

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

基于Python的FAO农业数据高效爬取与分析实战:从Scrapy到异步爬虫的进阶之路

本文将详细介绍如何使用Python最新技术爬取联合国粮农组织(FAO)的农业数据,涵盖从基础爬虫到高级异步爬虫的完整实现过程。文章包含5000余字的技术解析,提供完整的代码示例,并探讨数据处理与存储的最佳实践。

2201_76125261的博客 241

重写CompareTo

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

qq_39484718的博客 3498

基于Python的SEC Edgar文件高效爬取:最新技术与实战指南

本文详细介绍了如何使用Python最新技术高效爬取SEC Edgar数据库中的金融文件。我们将探讨SEC Edgar系统的结构、合法爬取注意事项,并使用现代Python库如Requests-HTML、aiohttp和Playwright实现多种爬取方案。文章包含完整的代码示例、性能优化技巧以及数据处理方法,为金融数据分析师、研究人员和开发者提供全面指导。关键词:SEC Edgar、Python爬虫、金融数据、异步爬取、Playwright、XBRL解析。

2201_76125261的博客 633

079、LVGL基础控件:消息框(Msgbox)

《LVGL消息框控件深度解析与避坑指南》 文章深入剖析了LVGL消息框控件的核心特性和使用技巧。消息框本质是带按钮的模态容器,而非独立窗口。作者分享了创建消息框的正确姿势、标题/内容设置方法、安全的按钮事件处理方式(避免直接调用close函数导致栈溢出),并详细介绍了模态/非模态实现、样式自定义、动态更新等实用技巧。针对常见问题如内存管理、按钮数量限制、动画效果等给出了专业建议,特别强调了消息框作为用户交互关键环节的优化重要性,建议通过异步删除、合理父对象选择等方式提升稳定性。文章包含大量实际项目经验总结,

m0_50546716的博客 153

C#重写Equals()

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

qq_27636823的博客 1528

AI 测试工程师 — 6 个月学习计划表

AI 转型测试工程师 —— 6 个月学习计划表

weixin_46453070的博客 1068

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

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

你真的会重写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

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

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、付费专栏及课程。

余额充值