Queue.Contains返回false而不是true

时间:2018-10-06 16:10:55

标签: c# collections

开发人员! 我终于失去了逻辑。该代码的问题是什么? 它必须为我返回true,因为cuz Queue包含名称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; }
        }
    }

1 个答案:

答案 0 :(得分:2)

您的代码运行正常,并且显示“ false”是绝对正常的。

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

每次编写代码new 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时会得到false的原因,因为默认情况下,引用类型是按引用进行比较的。

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

如果要比较Employee对象和其他语义(例如,通过比较它们的名称),则必须同时覆盖Equals和GetHashCode。我建议您仔细阅读有关C#的入门书籍,例如this one