1

关于 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 的另一个实例进行比较时,是否有任何特殊的“陷阱”我应该注意?

4

3 回答 3

4

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

,仅仅因为PersonimplementsIEquatable并不意味着SalaryInformationimplements IEquatablePerson和之间的关系SalaryInformation是一个组合,组合不关心接口实现。

因此,Equals实施Person取决于您何时认为两个人是相同的:

  • 如果他们共享相同的名字和姓氏,他们是否相同?
  • 如果它们也相同SalaryInformation,它们是否相同?

此外,如果您希望能够比较对象是否相等,则需要记住一些准则:

  1. 相等是一种等价关系,即它是
    a。反身的,
    b. 对称和
    c. 及物的。
  2. 请记住,null它不等于任何对象。
  3. 也总是覆盖GetHashCode

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

于 2012-03-05T16:55:03.913 回答
1

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

那么,如何在应用程序的上下文中将两个 Person 实例定义为相等的呢?姓和名的平等是否足够好?如果是这样,这就是您应该实施的方式IEquatable。有时使用的其他替代方法是根据一些生成的主键或一些已知的唯一值(例如国民保险号码)来定义相等性。

于 2012-03-05T16:54:58.470 回答
0

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

但正如其他人评论的那样,这在一定程度上取决于您要达到的目标。

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

于 2012-03-05T16:55:30.680 回答