C# 父类实现的 IEquatable<T> 接口,重写的相等性判断函数都能被子类继承

这篇具有很好参考价值的文章主要介绍了C# 父类实现的 IEquatable<T> 接口,重写的相等性判断函数都能被子类继承。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

实验代码

Son s1 = new(), s2 = new();

Console.WriteLine("_ = s1 == s2");
_ = s1 == s2;
Console.WriteLine();

Console.WriteLine("_ = s1 != s2;");
_ = s1 != s2;
Console.WriteLine();

Console.WriteLine("_ = s1.Equals(s2);");
_ = s1.Equals(s2);
Console.WriteLine();

Console.WriteLine("_ = ((object)s1).Equals(s2);");
_ = ((object)s1).Equals(s2);
Console.WriteLine();

Console.WriteLine("s1 is IEquatable<Father>");
Console.WriteLine(s1 is IEquatable<Father>);
Console.WriteLine();

Console.WriteLine("s1.GetHashCode()");
Console.WriteLine(s1.GetHashCode());
Console.WriteLine();

public class Father : IEquatable<Father>
{
	public virtual int A { get; set; }
	public virtual int B { get; set; }

	public override bool Equals(object? obj)
	{
		Console.WriteLine("object Equals");
		if (obj is not null and Father)
		{
			Father f = (Father)obj;
			return f.A == A && f.B == B;
		}

		return false;
	}

	public override int GetHashCode()
	{
		Console.WriteLine("GetHashCode");
		return 0;
	}

	public static bool operator ==(Father left, Father right)
	{
		Console.WriteLine("比较==");
		return left.Equals(right);
	}

	public static bool operator !=(Father left, Father right)
	{
		Console.WriteLine("比较!=");
		return !(left == right);
	}

	public bool Equals(Father? other)
	{
		Console.WriteLine("IEquatable Equals");
		return ((object)this).Equals(other);
	}
}

public class Son : Father
{
	public override int A { get => base.A; set => base.A = value; }
}

运行结果

_ = s1 == s2
比较==
IEquatable Equals
object Equals

_ = s1 != s2;
比较!=
比较==
IEquatable Equals
object Equals

_ = s1.Equals(s2);
IEquatable Equals
object Equals

_ = ((object)s1).Equals(s2);
object Equals

s1 is IEquatable<Father>
True

s1.GetHashCode()
GetHashCode
0

在父类重写的 Equals 方法,继承的 IEquatable 接口,重写的 == ,!= 运算符,重写的 GetHashCode 方法在子类中仍然是表现为被重写的状态。

子类实现 IEquatable 接口

现在让子类也实现 IEquatable 接口

Son s1 = new(), s2 = new();

s1.Equals(s2);

public class Father : IEquatable<Father>
{
	public virtual int A { get; set; }
	public virtual int B { get; set; }

	public override bool Equals(object? obj)
	{
		Console.WriteLine("object Equals");
		if (obj is not null and Father)
		{
			Father f = (Father)obj;
			return f.A == A && f.B == B;
		}

		return false;
	}

	public override int GetHashCode()
	{
		Console.WriteLine("GetHashCode");
		return 0;
	}

	public static bool operator ==(Father left, Father right)
	{
		Console.WriteLine("比较==");
		return left.Equals(right);
	}

	public static bool operator !=(Father left, Father right)
	{
		Console.WriteLine("比较!=");
		return !(left == right);
	}

	public bool Equals(Father? other)
	{
		Console.WriteLine("IEquatable Equals");
		return ((object)this).Equals(other);
	}
}

public class Son : Father, IEquatable<Son>
{
	public bool Equals(Son? other)
	{
		Console.WriteLine("IEquatable<Son>.Equals");
		return ((object)this).Equals(other);
	}
}

运行结果

IEquatable<Son>.Equals
object Equals

Equals 方法的重载

此时代码提示如下
C# 父类实现的 IEquatable<T> 接口,重写的相等性判断函数都能被子类继承,c#,开发语言
子类实现接口后,调用的默认就是子类实现的 Equals 方法。也可以用强制转换调用父类的 Equals 方法
C# 父类实现的 IEquatable<T> 接口,重写的相等性判断函数都能被子类继承,c#,开发语言
这里属于 Equals 方法的不同类型的重载。通过 public override bool Equals(object? obj) 重写的 Equals 方法也是一种重载。这个重载是每一个 object 的子类都有的,不重写这个方法时比较的是两个对象的引用是否相等。

所有判断相等性的运算符、方法必须一起重写

上面那些判断相等性的方法、运算符必须要么一起重写,要么全部不重写。实现了 IEquatable 接口后也要重写全部。如果不全部重写,这些不同的相等性判断方法返回结果不一致会造成混乱。

对象放到哈希表的过程

对象在放到哈希表里首先是计算哈希值,然后尝试放到哈希表中的对应位置。如果该位置已经有一个对象了,再调用 Equals 方法判断是不是同一个对象,如果是,就不再放一次了。如果不是,则说明发生了哈希冲突,此时会将新对象用链表挂在哈希表该位置。

重写 Equals 方法后,如果将对象放在哈希表里,必须重写 GetHashCode 方法

重写相等性判断方法时,如果想让对象能够在哈希表里正常工作,必须也重写 GetHashCode 方法。GetHashCode 方法原本是根据引用值生成哈希码,原本的相等性运算也是根据引用值。这种情况可以正常工作。但是,如果重写了 Equals 方法,不重写 GetHashCode 方法,会导致明明相等的两个对象返回的哈希值不同(因为他们的引用不同),于是哈希表中的两个位置储存了两个相等的对象。文章来源地址https://www.toymoban.com/news/detail-603905.html

重写 GetHashCode 的注意事项

  1. 不要使用会变化的字段生成哈希码。因为字段变化后,生成的哈希码不同,此时再调用 GetHashCode 方法得到的哈希码不同,这会导致字段变化后无法在哈希表中找到该对象了。
  2. 两个对象使用 Equals 方法判断相等性返回 true 时,GetHashCode 方法必须能够返回相同的值。否则会导致两个相等的对象具有不同的哈希值,这会导致哈希表中有重复的元素。

到了这里,关于C# 父类实现的 IEquatable<T> 接口,重写的相等性判断函数都能被子类继承的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【==是判断相等吗?---错辣】C++和JAVA中判断字符串值相等的区别

    参考文章:这里;这里;这里 C++中的 string 类型可以使用 == 和 != 来判断两个字符串的值是否相等;而JAVA不行,JAVA中 == 和 != 是用来 判断两个字符串的地址是否相同 (或者说是 对象是否相同 ,即 是否为同一个对 象)。 运行结果 结果解释 :C++中可以利用 == 来判断两个字符

    2023年04月21日
    浏览(59)
  • 判断两个数组是否相等

    在判断两个数组是否相等之前,我们应该弄清楚数组怎样才算相等,官方给的解释是这样的: Returns true if the two specified arrays of ints are equal to one another. Two arrays are considered equal if both arrays contain the same number of elements, and all corresponding pairs of elements in the two arrays are equal. In other

    2024年02月15日
    浏览(62)
  • Excel——TEXTJOIN函数实现某一列值相等时合并其他列

    一、TEXTJOIN函数介绍 公式=TEXTJOIN(分隔符, 忽略空白单元格, 字符串1…) 分隔符: 文本字符串,或者为空,或用双引号引起来的一个或多个字符,或对有效文本字符串的引用。如果提供一个数字,则将被视为文本。 忽略空白单元格: 如果为 TRUE,则忽略空白单元格,如果是Fa

    2024年02月04日
    浏览(65)
  • 判断两个vector数组是否相等

    判断两个vector数组是否相等是可以直接使用==或者!=的 因为vector内部都进行了相关运算符的重载,还可以进行比较大小 下面这道简单搜索题就用到了这个性质,浅看一下吧 【问题描述】给定一个n个整数的集合X={x1,x2,…xn}(X中可能包含重复元素)和整数y,找出和等于y的X的子集

    2024年02月12日
    浏览(65)
  • MATLAB-判断两矩阵是否相等

    相等的位置返回1,不相等则返回0 相等返回1,不相等返回0 注意:矩阵不可以包含NaN,因为这个函数中,NaN~=NaN。

    2024年02月06日
    浏览(98)
  • java 判断两个List是否包含 判断两个list相等

    java 判断两个List是否包含 判断两个list相等 https://blog.51cto.com/u_12855/7333853 1、直接使用equals()比较 众所周知,两个列表具有完全相同的元素并且具有完全相同的顺序时,它们是相等的。因此, 如果我们业务要求两个list顺序一致,可以使用equals()方法进行相等性检查: 即使

    2024年02月04日
    浏览(67)
  • Js如何判断两个数组是否相等?

    日常开发,时不时会遇到需要判定2个数组是否相等的情况,需要实现考虑的场景有: 先判断长度,长度不等必然不等 元素位置 其他情况考虑 \\\'1\\\' 和 1 (Object的key是字符串, Map的key没有限制) NaN null 和 undefined 数组自带的方法,比较适合的有: every、some、filter、findIndex 。 这种

    2024年02月22日
    浏览(69)
  • 记录--如何判断两个数组的内容是否相等

    给定两个数组,判断两数组内容是否相等。 不使用排序 不考虑元素位置 例: 思考几秒:有了😀😀 直接遍历第一个数组,并判断是否存在于在第二个数组中 求差集, 如果差集数组有长度,也说明两数组不等(个人感觉比上面的麻烦就不举例了) 细心的小伙伴就会发现:N

    2024年02月08日
    浏览(158)
  • Go语言如何判断两个对象是否相等

    在编程中,判断两个对象是否相等是一项常见的任务,同时判断对象是否相等在很多情况下都非常重要,例如: 单元测试 :编写单元测试时,经常需要验证函数的输出是否符合预期,这涉及到比较对象是否相等。 数据结构操作 :在使用 map 等数据结构时,可能需要判断两个对

    2024年02月07日
    浏览(145)
  • 在JS中如何判断两个对象是否相等

    在JavaScript中,判断两个对象是否相等有多种方法,取决于你对 相等 的定义以及对象属性的类型。以下是几种常见的方法:   1. 严格相等运算符 (===) 使用 === 运算符可以比较两个对象是否引用同一个对象。如果两个变量引用了同一个对象,则它们是相等的,否则它们是不相等

    2024年02月03日
    浏览(60)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包