c# - 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; }
}
}
解决方案
您的代码运行良好,打印“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# 的介绍性书籍,比如这本
推荐阅读
- vba - 用于执行不同分析的 VBA 数据结构
- javascript - 使用常用js库的功能
- typescript - TypeScript 模块导入路径映射
- java - 如何从具有动态条目的文件中拆分
- sparql - 可靠地查询 SPARQL 端点并在本地缓存结果
- c# - 动态组合框参数重置
- identityserver4 - 调用 /connect/userinfo 返回错误“未处理的异常:序列包含多个匹配元素”
- tensorflow - tensorflow 中 Masking() Keras 函数的等价性是什么?batch norm、conv 和 relu 是否支持 Masking?
- asp.net - Windows 身份验证不适用于 IIS Express 10
- unit-testing - 测试在 Golang 中加载 JSON 配置文件的方法