📜  c# 对象列表包含对象返回不正确的布尔值 - C# (1)

📅  最后修改于: 2023-12-03 14:59:42.206000             🧑  作者: Mango

C# 对象列表包含对象返回不正确的布尔值

在 C# 中,使用 List<T> 可以方便地存储同一类型的对象集合。通常我们会使用 Contains() 方法来判断一个对象是否包含在列表中。然而,有时候会出现返回不正确的布尔值的情况,这种情况往往是因为对象的比较方式不正确导致的。

问题描述

以下代码是一个示例,定义了一个 Person 类,然后创建了一个 List<Person> 对象 people,并添加了两个 Person 对象。接着,使用 Contains() 方法来判断列表中是否包含这两个对象:

class Program
{
    static void Main(string[] args)
    {
        List<Person> people = new List<Person>();
        people.Add(new Person { Name = "Tom", Age = 18 });
        people.Add(new Person { Name = "Jerry", Age = 20 });

        Person person1 = new Person { Name = "Tom", Age = 18 };
        Person person2 = new Person { Name = "Jerry", Age = 20 };

        bool contains1 = people.Contains(person1);
        bool contains2 = people.Contains(person2);

        Console.WriteLine(contains1);   // 输出 False,期望输出 True
        Console.WriteLine(contains2);   // 输出 False,期望输出 True
    }
}

class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
}

上面的代码期望的输出是 True,但实际的输出却是 False。这是因为在 Person 类中没有重写 Equals() 方法和 GetHashCode() 方法。

解决方法

若要让 Contains() 方法正确地判断对象是否包含在列表中,需要在 Person 类中重写 Equals() 方法和 GetHashCode() 方法。以下是修改后的代码:

class Program
{
    static void Main(string[] args)
    {
        List<Person> people = new List<Person>();
        people.Add(new Person { Name = "Tom", Age = 18 });
        people.Add(new Person { Name = "Jerry", Age = 20 });

        Person person1 = new Person { Name = "Tom", Age = 18 };
        Person person2 = new Person { Name = "Jerry", Age = 20 };

        bool contains1 = people.Contains(person1);
        bool contains2 = people.Contains(person2);

        Console.WriteLine(contains1);   // 输出 True
        Console.WriteLine(contains2);   // 输出 True
    }
}

class Person
{
    public string Name { get; set; }
    public int Age { get; set; }

    public override bool Equals(object obj)
    {
        if (obj == null) return false;
        if (!(obj is Person)) return false;
        var p = obj as Person;
        return Name == p.Name && Age == p.Age;
    }

    public override int GetHashCode()
    {
        return Name.GetHashCode() ^ Age;
    }
}

Equals() 方法中,我们判断了对象是否为空,是否是 Person 类型。如果满足条件,就比较了 NameAge 属性的值。在 GetHashCode() 方法中,我们使用了 Name 属性的哈希值异或上 Age 属性的值作为哈希码,这是一种简单的哈希算法。

通过重写这两个方法,现在我们可以正确地判断对象是否包含在列表中了。

小结

在 C# 中,使用 List<T> 存储对象集合时,需要重写 Equals() 方法和 GetHashCode() 方法,以便正确地判断对象包含情况。否则,Contains() 方法可能会返回错误的布尔值。