执行IEquatable级联

本文关键字:级联 IEquatable 执行 | 更新日期: 2023-09-27 18:26:39

关于IEquatable,我有一个非常简单的问题。给定以下基本类:

public class Person
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public SalaryInformation AnnualSalaryInformation { get; set; }
    }
    public class SalaryInformation
    {
        public string TaxCode { get; set; }
        public string SalaryBand { get; set; }
        public BankInformation AccountInfo { get; set; }
    }
    public class BankInformation
    {
        public string SortCode { get; set; }
        public string AccountNumber { get; set; }
    }

如果我想与Person对象进行平等比较,我会怎么做?如果我在Person类上实现IEquatable接口,它会自动级联到该类中的任何对象吗?还是我必须在所有类上显式实现该接口?

如果我必须在所有类上实现接口,那么在将Person的一个实例与Person的另一个实例进行比较时,是否有任何特定的"gotchas"需要我注意?

执行IEquatable级联

对象之间的相等可以采取多种形式,具体取决于您的需求。回答您的问题:

Person实现IEquatable并不意味着SalaryInformation实现IEquatablePersonSalaryInformation之间的关系是一个组合,组合不关心接口实现。

因此,PersonEquals实现取决于何时考虑两个人是相同的:

  • 如果他们的名字和姓氏相同,他们是一样的吗
  • 如果它们也有相同的SalaryInformation,它们是相同的吗

此外,如果你想比较对象的相等性,有几个准则需要记住:

  1. 平等是一种等价关系,即
    a.反射性,
    b.对称且
    c.可传递
  2. 请记住,null不等于任何对象
  3. 也始终覆盖GetHashCode

如果你掌握了窍门,做对并不难,但如果你从来没有做过,就会出现各种各样的问题。

这完全取决于您自己对两个Person实例何时相等的定义!这里没有魔法,在Person上实现IEquatable不会以任何方式级联。

那么,如何在应用程序的上下文中将两个Person实例定义为相等?姓氏和名字平等就足够了吗?如果是这样,那就是应该如何实现IEquatable。有时使用的其他替代方案是基于某些生成的主键或某些已知的唯一值(如国民保险号码)来定义相等性。

是的,我会在您使用的每个类上实现这一点。

但正如其他人所评论的那样,这在一定程度上取决于你想要实现的目标。

如果实现Equals和GetHashCode(两者都需要),则通常应该尝试在比较中只包含只读字段。除此之外,您必须确保GetHashCode能很好地处理Equals(例如,如果Equals返回true,则不会返回不同的值),当然Equals应该是对称的。