首页 > 编程语言 >C#的相等判断

C#的相等判断

时间:2024-09-02 21:15:09浏览次数:6  
标签:相等 Point C# Object Equals 判断 重写

什么是相等

在C#中我们经常会需要判断两个变量是否相等,相等理论上有两种:

  • 同一性(identity),即是否两个变量是否指向同一个对象。
  • 相等性(equality),即两个变量内部的值是否相同,例如两个字符串的内容是否相同。

显然如果两个变量是相同对象,那么它们也必然相等。根据具体使用的上下文我们可能需要判断同一性或者相等性之一,因此就需要了解如何进行判断。

C#判断相等的方式

C#的System.Object类提供了如下方式来判断对象的相等性:

public static bool Equals(Object? objA, Object? objB);
public static bool ReferenceEquals(Object? objA, Object? objB);
public virtual bool Equals(Object? obj);
operator ==;

首先是ReferenceEquals,这个顾名思义就是判断两个变量是否引用同一个对象,在需要明确判断引用相等的时候可以使用这个函数。

其次是Equals方法,这个方法在Object类中定义,默认实现是调用ReferenceEquals,即判断引用是否相等。但是我们看到这是一个虚方法,因此很多类型重写了这个方法,例如String类型,重写后比较的是字符串的内容是否相同。

而相等运算符和Equals方法类似,也可以被重载,以实现自定义类型的相等判断。根据官方文档介绍,对于值类型是判断其内部值是否相同,对于引用类型是默认判断是否引用同一对象,对于委托和字符串等也有各自的实现。

值得注意的是,用户定义的struct类型默认没有支持==操作符,但是可以使用ValueType的Equals方法来判断两个值类型的内部值是否相同,例如:

static void Main(string[] args)
{
    Point p1 = new Point(1, 1);
    Point p2 = new Point(1, 1);
    Console.WriteLine("p1 == p2:{0}", p1.Equals(p2)); // 输出 p1 == p2:True
    Console.WriteLine("p1 == p2:{0}", p1 == p2); // 编译错误 Operator '==' cannot be applied to operands of type 'Point' and 'Point'
}

internal struct Point
{
    private Int32 m_x, m_y;
    public Point(Int32 x, Int32 y)
    {
        m_x = x;
        m_y = y;
    }
}

综上,C#提供了多种方式来判断对象的相等性,包括引用相等和值相等,开发者需要根据具体需求选择合适的方法进行判断。

如何自定义相等判断

我们自定义的类如果需要实现自己的相等判断逻辑,那么可以重载Object的public virtual bool Equals(Object? obj)方法以及重写==操作运算符,如果重写了其中之一,那么推荐也重写另一个相等判断,否则可能由于使用习惯使用了没有重写的相等判断造成bug。

重写时需要注意相等性判断要符合一下特性:

  • 自反性。x.Equals(x) 应该返回 true
  • 对称性。x.Equals(y) 应该返回和 y.Equals(x) 相同的结果
  • 可传递。x.Equals(y) 和 y.Equals(z) 都返回 true,那么 x.Equals(z) 也应该返回 true
  • 一致性。x.Equals(y) 多次调用应该返回相同的结果,除非x或y的值发生了变化。

如果重写了public virtual bool Equals(Object? obj)方法,那么也应该重写GetHashCode方法,因为相等的对象必须有相同的哈希码,否则以这个类的对象作为key来索引时会导致相同的对象索引到不同的数据,而且编译器也会给出有一个编译警告

除了使用继承来的Object的相关方法来判断相等,我们还可以继承IEquatable接口实现自己的Equals方法,该方法和Object的Equals方法类似,但是类型更安全,因为它的参数是该类型的变量,而不是Object对象,不需要装箱和拆箱操作。

标签:相等,Point,C#,Object,Equals,判断,重写
From: https://www.cnblogs.com/wenxuanh/p/18393548

相关文章

  • PyTorch自定义模型类
    使用Pytorch自己建立一个模型类:继承初始  建立一个模型的类,一定要继承nn,Module父类,初始化:def__init__(self):super(self).__init__():如果不这样操作就使用不了继承中初始化,也使用不了继承的一些函数。 建立自己的网络层图中初始化后的self.conv都是使......
  • CF 2100-2400 strings 乱做
    CF1995DCases显然如果选了某个字符那么不妨选它出现的所有位置。check方式等价于相邻两个选择的位置间距\(\lek\),等价于连续\(k\)个必须选一个(最后一个必须选)枚举位置维护字符集是做不了的,状态数\(O(n2^c)\)无法优化考虑枚举字符集\(s\)。设原串连续\(k\)个字符的字......
  • Java API:Object and Objects
    JavaAPI:ObjectandObjects目录JavaAPI:ObjectandObjects1Object1.1常用方法1.1Object类的toString方法1.1.1示例1.2equals1.2.1示例1.2.2面试题2Objects2.1示例1Object类Object是类层次结构的根。每个class都有Object作为超类。所有对象(包括数组)都实现此类的方......
  • Java API:BigDecimal
    JavaAPI:BigDecimal目录JavaAPI:BigDecimal1BigDecimal2示例1BigDecimalBigDecimal类使用户完全控制舍入行为。如果未指定舍入模式,并且无法表示确切的结果,则抛出异常;否则,可以通过向操作提供适当的MathContext对象来进行计算,以选择精度和舍入模式。在这两种情况下,都......
  • 浙江省会计人员继续教育刷课脚本-JavaScript编写
    脚本学习网站:浙江省会计人员继续教育:https://jxjy.czt.zj.gov.cn/front/jxjy.html脚本地址:浙江省会计人员继续教育-刷课脚本:https://greasyfork.org/zh-CN/scripts/506412-浙江省会计人员继续教育-刷课脚本教程1.插件安装(以MicrosoftEdge浏览器为例)打开最中间那个蓝色......
  • MacBook Pro M3 安装 Node.js v14 的兼容性
    1、MacBookProM3可以安装Node.jsv14,但需要一些额外的步骤,因为Node.jsv14并没有为ARM64构建的版本。2.解决方法可以通过安装Rosetta来解决这个问题。Rosetta是一个翻译应用程序,允许为Intel芯片(或旧一代Mac)构建的应用程序在AppleSilicon下运行。安装Rosetta......
  • 「漏洞复现」用友NC link/content SQL注入漏洞
    0x01 免责声明请勿利用文章内的相关技术从事非法测试,由于传播、利用此文所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,作者不为此承担任何责任。工具来自网络,安全性自测,如有侵权请联系删除。本次测试仅供学习使用,如若非法他用,与平台和本文作者无关,需......
  • C语言:大小端模式、判断大小端、大小端转换
    目录1.什么是大端和小端2.为什么会存在大小端的问题3.判断主机字节序(主机大小端)3.1使用联合体(union)3.2使用指针3.3强制转为char类型法4.大小端转换1.什么是大端和小端对于一个存储空间大于1个字节的数据,在内存中有两种存储模式,大端模式(big-end......
  • 26. 在集合中删除元素时,为什么使用Iterator.remove()而不是Collection.remove()?
    在遍历集合时,推荐使用Iterator.remove()方法来删除元素,而不是Collection.remove()方法。这主要是出于以下几个原因:1.避免ConcurrentModificationExceptionIterator.remove():在使用Iterator遍历集合时,Iterator会跟踪集合的结构性修改(即增加或删除元素)。Iterator.remove(......
  • C基础练习
    c基础练习题设有说明:charw;intx;doubley;则表达式w*x-y值的数据类型为()。A.float   B.char    C.int    D.double答案:D解析:在C语言中,当不同类型的数据进行算术运算时,较低类型的数据会被提升(或称为转换)到较高类型的数据。此处类型最高的是doubl......