C#的相等性比较

C#比较对象的相等性 对于相等的机制所有不同,这取决于比较的是引用类型还是值类型。下面分别介绍引用类型和值类型的相等性。 1.比较引用类型的相等性    System.Object定义了三种不同的方法,来比较对象的相等性:ReferenceEquals()和两个版本的Equals()。再加上比较运算符(==),实际上有4种进行比较相等的方式。 1.1 ReferenceEquals()方法 阅读详情
Equals() 和运算符 == 的重载准则(C# 编程指南)

 

C# 中有两种不同的相等:引用相等和值相等。值相等是大家普遍理解的意义上的相等:它意味着两个对象包含相同的值。例如,两个值为 2 的整数具有值相等性。引用相等意味着要比较的不是两个对象,而是两个对象引用,这两个对象引用引用的是同一个对象。这可以通过简单的赋值来实现,如下面的示例所示:

System.Object a = new System.Object();
System.Object b = a;
System.Object.ReferenceEquals(a, b);  //returns true

在上面的代码中,只存在一个对象,但存在对该对象的多个引用:a 和 b。由于它们引用的是同一个对象,因此具有引用相等性。如果两个对象具有引用相等性,则它们也具有值相等性,但是值相等性不能保证引用相等性。

若要检查引用相等性,应使用 ReferenceEquals。若要检查值相等性,应使用 Equals 或 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。

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

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 实现:

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;
    }
}

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

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

//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);
}
Note注意

运算符 == 的重载中的常见错误是使用 (a == b)、(a == null) 或 (b == null) 来检查引用相等性。这会导致调用重载的运算符 ==,从而导致无限循环。应使用 ReferenceEquals 或将类型强制转换为 Object 来避免无限循环。

 
C#元组的相等性比较 元组作为轻量级的数据结构,在c#中具有广泛的引用。但是元组的比较一直以来都是对于成员的依次比较。好在C#7.3开始,引入了元素的相等性比较,让元组的易用性有了大幅提升。 绑定 微软对此的介绍是“从 C# 7.3 开始,元组类型支持 == 和 != 运算符。 这些运算符按顺序将左边参数的每个成员与右边参数的每个成员进行比较,且比较是短路计算” 所以我们可以写出这样的代码,对元组进行比较 var l... 阅读详情

相关推荐

聊聊C#中==和Equals

泛型版本:EqualityComparer<T>.Default.Equals(T x, T y) 提供了一个泛型版本的 Equals 方法,它对于未重写 Equals 的类型使用默认的引用比较,对于重写了 Equals 的类型则使用重写后的实现。引用类型:对于引用类型,== 默认比较的是两个对象的引用是否指向内存中的同一个位置(即是否是同一个对象的引用)。默认实现:Object.Equals(object obj) 的默认实现与 == 对于引用类型的行为相同,即比较两个引用是否指向同一个对象。

java专栏 742

C语言编程新手:如何判断结构体(struct)相等?

本文介绍了C语言中比较两个结构体相等的方法:逐成员比较适用于复杂数据类型,简单有效;memcmp适用于简单数据类型,但需小心内存对齐和浮点数比较问题。

Somnus陳的博客 2370

重载equals方法示例

重载equals方法示例重载equals方法示例重载equals方法示例重载equals方法示例重载equals方法示例

浅析c#中==操作符和equals方法

  在之前的文章中,我们讲到了使用C#中提供的Object类的虚Equals方法来判断Equality,但实际上它还提供了另外一种判断Equality的方法,那就是使用==运算符。许多童鞋也许会想当然的认为==不过是Equals方法的语法糖而已,然而事实却并非如此。尽管从实现上来说,它给出的判定结果往往和Object.Equals方法一致,但这不是必须的,因为两者的实现机制完全相同。下面就让我们看...

weixin_34377919的博客 368

51单片机———UART串口通信

传统理解就是信息的传输与交换。单片机与单片机之间,单片机与电脑之间,以及单片机与各式各样的模块之间都可以进行通信。如果没有通信,那么单片机的功能仅仅局限于它本身,它没办法从其他设备获取有用信息,也无法将自己产生的信息告诉其他设备,这样子单片机与外围器件的合作就会收到限制,没办法完成更多的功能,就像一个没办法拓展业务的公司。:实现我们程序当中写的P0=0xFC,就是一次同时对8位进行信号的输出;习惯上,我们还称P0、P1、P2、P3为单片机的4组并行总线:实现低位先发 高位在后。

m0_74225397的博客 3296

AD20丝印层导入图片logo保姆级教程(附黑白预览避坑技巧)

本文提供了一份详尽的AD20丝印层导入图片Logo的实战指南。核心在于将图片预处理为高质量的单色BMP位图,并独家分享了利用Windows画图工具进行“黑白预览”的关键技巧,以提前规避转换失真。教程涵盖了从脚本获取、图片处理、参数设置到生产规范的完整流程,帮助硬件工程师高效、准确地在PCB的Top Overlay层添加个性化标识。

weixin_29194255的博客 386

C#经典语法总结(六)Equals() 和运算符 == 的重载准则

 C# 中有两种不同的相等:引用相等和值相等。值相等是大家普遍理解的意义上的相等:它意味着两个对象包含相同的值。例如,两个值为 2 的整数具有值相等性。引用相等意味着要比较的不是两个对象,而是两个对象引用,且两者引用的是同一个对象。这可以通过简单的赋值来实现,如下面的示例所示:System.Object a = new System.Object();System.Object

马辉的专栏 1863

【STM32项目】老人健康跌倒检测系统实现(附教程PCB资料)

功能概述 跌倒检测 倾倒告警,人体角度倾斜至阈值触发蜂鸣报警 异常运动,加速度超过正常行动阈值时触发报警 心率监测 实时检测心率数据 血氧监测 实时检测采集血氧 血压测量 血压在线测量 红外体温 非接触体温采集方案 接触式体温采集方案 实时定位 中科微GPSGT-U12双频GPS北斗 GLONASS IRNSS定位系统 NEMA数据解析 可扩展高精度定位方案厘米级 屏幕显示 数据采集显示 告警阈值设置 语音提示 1欢迎使用老人智慧监测系统

洋洋的博客 1万+

C#相等性比较

本文阐述C#中相等性比较,其中主要集中在下面两个方面 ==和!=运算符,什么时候它们可以用于相等性比较,什么时候它们不适用,如果不使用,那么它们的替代方式是什么? 什么时候,需要自定一个类型的相等性比较逻辑 在阐述相等性比较,以及如何自定义相等性比较逻辑之前,我们首先了解一下值类型比较和引用类型比较 值类型比较对比引用类型比较 C#中的相等性比较有两种: 值类型相等,两个...

aoding8407的博客 507

【MBD开发】Simulink中的枚举

01 什么是枚举 按百度百科的词条【枚举】是在编程语言中用来存储一组固定的常量。不同编程语言的枚举语法也不一样,以C语言为例。 typedef enum{ GEAR_P, //0:P挡 GEAR_R, //1:倒挡 GEAR_N, //2:空挡 GEAR_D, //3:前进}_GEAR; 上面枚举了一个_GEAR数据,用GEAR_P表示0,GEAR_R表示1……​​​​​​​ if(current_gear==GEAR..

f6723的博客 3096

GOM引擎单机传奇架设全攻略——从DBC2000配置到登录器生成

本文详细解析了使用GOM引擎架设单机传奇的完整流程,从DBC2000的安装配置、服务端部署、引擎控制器设置,到登录器生成与客户端补丁放置。文章重点解决了单机架设中的常见问题,如数据库路径配置、IP地址设置及Key.lic文件处理,旨在帮助玩家快速搭建稳定的个人游戏环境,体验GM乐趣。

weixin_28318011的博客 631

C#深入理解比较对象的相等性

C#比较对象的相等性 1、比较引用类型的相等性 引用类型都继承自object类型,object类型有如下的用来比较对象相等性的方法: 1)static bool ReferenceEquals(Object objA, Object objB) 该方法是一个静态方法,比较的是两个对象的引用,其中null等于null。 2)virtual bool Equals(Object obj); 该方法是一个虚方法,可以在自己的类中重写它,从而按值来比较对象。 3)static bool Equals(Object

目标:MVP 324

Fluent温度超限调试:从能量方程到网格优化的实战指南

本文深入解析Fluent中温度超限问题的诊断与解决方法,从能量方程机制到网格优化策略,提供实战指南。通过分析温度与焓的换算关系,探讨典型场景如能量方程发散、局部网格质量差等,并给出五步调试法及高级命令应用,帮助工程师有效解决温度计算异常问题。

weixin_29045585的博客 530

C# 比较对象的相等性

对象相等的机制有所不同,这取决于比较的是引用类型(类的实例)还是值类型(基本数据类型、结构或枚举的实例)。下面分别介绍引用类型和值类型的相等性。01比较引用类型的相等性System.Obj...

zls365365的博客 921

【深度学习新浪潮】OpenClaw跟机器人行业有哪些很好的研究结合点?

OpenClaw正通过"AI大脑+机器人肢体"的深度融合,重新定义机器人与人类的交互方式和自主操作能力。近期ROSClaw框架发布、人形机器人集成和空间计算试验等进展,标志着OpenClaw已从概念验证阶段进入实际应用落地期,为机器人行业带来了自然语言控制普及化具身智能平民化和跨平台开发标准化三大变革机遇。

专注:太空算力、AI infra、异构调度、大模型成本工程 229

基于 Simulink 的固态变压器(SST)多级协同控制实战教程

《固态变压器多级协同控制仿真指南》摘要: 本教程详细讲解了基于Simulink的固态变压器(SST)三级架构建模与控制方法。核心内容包含:1)搭建级联H桥整流(CHB)、双有源桥(DAB)和逆变器(VSI)的三级主电路;2)提出创新的多级协同控制策略,通过功率前馈实现输入输出级动态匹配;3)给出系统级功率平衡、单元级均压控制的具体实现方案。教程特别强调解决实际工程中的关键问题:代数环处理、软启动设计和刚性系统求解器选择,并提供了硬件在环(HIL)仿真建议。附带的MATLAB代码示例可直接用于实现电容电压均衡

xiaoheshang_123的博客 120

【转载】C#相等性比较

本文阐述C#中相等性比较,其中主要集中在下面两个方面 ==和!=运算符,什么时候它们可以用于相等性比较,什么时候它们不适用,如果不使用,那么它们的替代方式是什么? 什么时候,需要自定一个类型的相等性比较逻辑 在阐述相等性比较,以及如何自定义相等性比较逻辑之前,我们首先了解一下值类型比较和引用类型比较 值类型比较对比引用类型比较 C#中的相等性比较有两种: 值类型相等,两个值在某种场景下相等 引...

weixin_33893473的博客 159

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

C# 实现一个基于值相等性比较的字典

C# 实现一个基于值相等性比较的字典Intro今天在项目里遇到一个需求,大概是这样的我要比较两个 JSON 字符串是不是相等,JSON 字符串其实是一个 Dictionary<st...

dotNET跨平台 406

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

C#比較对象的相等性

   对于相等的机制全部不同,这取决于比較的是引用类型还是值类型。以下分别介绍引用类型和值类型的相等性。 1.比較引用类型的相等性    System.Object定义了三种不同的方法,来比較对象的相等性:ReferenceEquals()和两个版本号的Equals()。再加上比較运算符(==)。实际上有4种进行比較相等的方式。 1.1 ReferenceEquals...

weixin_33730836的博客 100

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

【C# ValueTuple 相等性深度解析】:揭秘值元组比较背后的底层机制与性能陷阱

深入解析C# ValueTuple 的相等性比较机制,揭示其基于值的递归比较原理与性能影响。涵盖常见应用场景、Equals方法实现及装箱陷阱,助你写出更高效的元组比较代码。值得收藏

LogicGap的博客 894

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

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

ProceChat的博客 582
上一篇: 编程容易出错地方汇总( 边界编程)
下一篇: 身份证号校验的 js
dotnet90
博客等级 码龄23年 102粉丝 413原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值