【问题标题】:Queue.Contains returns false instead of trueQueue.Contains 返回 false 而不是 true
【发布时间】:2018-10-06 16:10:54
【问题描述】:

开发者! 我终于失去了逻辑。这段代码有什么问题? 它必须为我返回 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


    【解决方案1】:

    您的代码运行良好,打印“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 时会得到错误的原因,因为默认情况下,引用类型是按引用进行比较的。

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-03-23
      • 2014-04-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多