C# · 12月 27, 2021

c# – Dictionary.ContainsKey始终返回False

那么我试图创建一个小的应用程序,可以节省一些员工姓名,年龄和工资.所以我决定用Dictionary来设置每个员工的工资,我想出了这个代码

var employeeSalaryDictionary = new Dictionary<Employee,int>();employeeSalaryDictionary.Add(new Employee { Name = “Chuck”,Age = 37 },1000);employeeSalaryDictionary.Add(new Employee { Name = “Norris”,2000);employeeSalaryDictionary.Add(new Employee { Name = “Rocks”,Age = 44 },3000);Employee employeeToFind = new Employee { Name = “Chuck”,Age = 37 };//or evenEmployee employeeToFind = new Employee { Name = “Chuck”};//Always False…bool exists = employeeSalaryDictionary.ContainsKey(employeeToFind);

员工班

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

然而,正如我发表的评论或主题标题所述,.ContainsKey总是返回False,尽管我尝试了两种方式,如代码所示.

解决方法 您没有使用DictionaryqueryComparer< T>中的Dictionary构造函数.您也没有在Employee类上实现自定义的等式.

所以现在字典是通过参考比较员工.当你新的员工,你有一个不同的参考,即使例如名字可能是一样的

这可能是最简单的方式来实现自己的IEqualityComparer< Employee>,您可以在其中选择哪些成员将用于等式比较,并将其传递给字典的构造函数.

作为承诺,片段:

//ReSharper’s courtesypublic sealed class NameAgeEqualityComparer : IEqualityComparer<Employee>{ public bool Equals(Employee x,Employee y) { if (ReferenceEquals(x,y)) return true; if (ReferenceEquals(x,null)) return false; if (ReferenceEquals(y,null)) return false; if (x.GetType() != y.GetType()) return false; return string.Equals(x.Name,y.Name) && x.Age == y.Age; } public int GetHashCode(Employee obj) { unchecked { return ((obj.Name != null ? obj.Name.GetHashCode() : 0) * 397) ^ obj.Age; } }}

接着:

var employeeSalaryDictionary = new Dictionary<Employee,int>(new NameAgeEqualityComparer());employeeSalaryDictionary.Add(new Employee { Name = “Chuck”,Age = 37 };bool exists = employeeSalaryDictionary.ContainsKey(employeeToFind); // true!

为了完整性,这里是唯一的比较器(也是ReSharper的礼貌):

public sealed class NameEqualityComparer : IEqualityComparer<Employee> { public bool Equals(Employee x,Employee y) { if (ReferenceEquals(x,y)) return true; if (ReferenceEquals(x,null)) return false; if (ReferenceEquals(y,null)) return false; if (x.GetType() != y.GetType()) return false; return string.Equals(x.Name,y.Name); } public int GetHashCode(Employee obj) { return (obj.Name != null ? obj.Name.GetHashCode() : 0); } }

但是,正如您所注意到的那样,您必须确定在创建字典时将使用哪个比较器进行键比较.以后不能改变…