如何检查列表中对象的属性是否相等?

How to check if properties across objects in a list are equal?

我在一个列表中有两个对象,我想确保这些对象的所有属性都具有相同的值。

例如:

List<Person> persons = new List<Person>
{
    new Person { Id = "1", Name = "peter" },
    new Person { Id = "1", Name = "peter" }
};

现在我想得到 true,因为两个对象的属性相同。我尝试使用以下 lambda 表达式。

var areEqual = persons.All(o => o == persons.First());

但我在 areEqual 中得到 false。我无法理解为什么会这样,想知道如何正确地做到这一点。

您可以使用以下方法查看所有元素是否相同:

persons.Distinct().Count() == 1

如果它为零,则首先没有条目,如果它大于 1,则您有不同的条目。

现在...您如何确保 .Distinct() 调用知道两个对象何时相同?

  • 选项 1:Person 已经是 record。伟大的。内置功能。完成。

  • 选项 2:Person 实现 IEquatable<Person> 并执行您想要的检查。

  • 选项 3:Person 以您需要的方式自行覆盖 Object.EqualsObject.GetHashCode

  • 选项 4:Person 不是以上任何一项,您不想更改它以选中其中一个框。然后你仍然可以实现你自己的 IEqualityComparer<Person> 并将它的实例传递给 distinct 方法,如下所示:

    persons.Distinct(new MyCustomPersonEqualityComparer()).Count() == 1
    

Person是引用类型,默认==是进行内存的位置相等检查。为了执行您自己的相等性检查,您必须实施 IComparable<Person>.

您也可以使用 record 而不是 class,这在幕后实现了对记录的 public 属性的相等性检查。

public record Person
{
    public string Id { get; set; }
    public string Name { get; set; }
}

如果您的项目少于 2 个,则此查询将毫无意义。因此,取第一个元素与其余元素进行比较

var allAreSame = persons
    .All(p => p.Id == persons[0].Id && p.Name == persons[0].Name);

或者(更快的方式)

var allAreSame = !persons
    .Any(p => p.Id != persons[0].Id || p.Name != persons[0].Name);