首页 > 解决方案 > Queue.Contains 返回 false 而不是 true

问题描述

开发商!我终于失去了逻辑。这段代码有什么问题?它必须为我返回 true,因为队列包括名称 Jack。为什么不?我是否以不正确的方式使用方法?感谢您回答我的简单问题!

 namespace DataStructures
    {
        class Program
        {
            static void Main(string[] args)
            {
                Queue<Employee> line = new Queue<Employee>();
                line.Enqueue(new Employee { Name = "Jack" });
                line.Enqueue(new Employee { Name = "Nick" });
                line.Enqueue(new Employee { Name = "Vova" });
                line.Enqueue(new Employee { Name = "Andrew" });

                Console.WriteLine(line.Contains(new Employee { Name = "Jack" }));
                Console.ReadLine();
            }
        }

        class Employee
        {
            public string Name { get; set; }
        }
    }

标签: c#collections

解决方案


您的代码运行良好,打印“false”是绝对正常的。

您称为 Employee 的类型是一个类,因此它是一个引用类型。默认情况下,引用类型按引用进行比较。这是 System.Object 中定义的相等语义,它被所有类继承,除非提供了对 Equals 方法的覆盖。

每次编写代码 new Employee() 时,您都在创建类employee 的新实例:这基本上意味着您正在创建一个新对象并且您正在堆中分配新内存(这是计算机内存的一部分C# 对象所在的位置)。

看下面的代码:

var mark = new Employee(){ Name = "Mark" };
var henry = new Employee() { Name = "Henry" };

var areEquals = mark.Equals(henry);
var areSameReference = Object.ReferenceEquals(mark, henry);

Console.WriteLine(areEquals); // this will print false
Console.Writeline(areSameReference); // this will print false

在上面的代码中,您创建了 Employee 类的两个不同实例,并在堆中创建了两个不同的对象(换句话说,您分配了两个不同的内存空间以存储两个不同的对象)。这就是为什么当您调用 Equals 时会得到错误的原因,因为默认情况下,引用类型是按引用进行比较的。

当您在变量 mark 和 henry 上调用 Object.ReferenceEquals 时,您会得到错误,因为该变量引用了两个不同的内存地址,因为您创建的两个对象存储在堆的不同内存地址中。

如果您想用不同的语义比较您的 Employee 对象,例如通过比较它们的名称,您必须同时覆盖 Equals 和 GetHashCode。我建议你仔细阅读一本关于 C# 的介绍性书籍,比如这本


推荐阅读