Dictionary.ContainsKey Always Returns False
c#, dictionary
Solution
You're not using the `Dictionary` constructor that takes in the `IEqualityComparer<T>` and neither have you implemented custom equality on the `Employee` class.
So right now the dictionary is comparing employees by reference. When you `new` an employee, you have a different reference, even though e.g. name might be the same.
Probably the easiest way here would be to implement your own `IEqualityComparer<Employee>`, where you could pick which members will be used for equality comparison, and pass it to the dictionary's constructor.
[EDIT] As promised, snippets:
//ReSharper's courtesy
public 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;
}
}
}
And then:
var employeeSalaryDictionary = new Dictionary<Employee, int>(new NameAgeEqualityComparer());
employeeSalaryDictionary.Add(new Employee { Name = "Chuck", Age = 37 }, 1000);
employeeSalaryDictionary.Add(new Employee { Name = "Norris", Age = 37 }, 2000);
employeeSalaryDictionary.Add(new Employee { Name = "Rocks", Age = 44 }, 3000);
Employee employeeToFind = new Employee { Name = "Chuck", Age = 37 };
bool exists = employeeSalaryDictionary.ContainsKey(employeeToFind); // true!
For completeness, here's name-only comparer (also ReSharper's courtesy):
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);
}
}
But, as you noticed, you have to decide which comparer you will use for key-comparison when you create a dictionary. That can't be changed later on...
Problem
Well i am trying to create a small application that saves some employees Names, Ages as well as salaries. So i decided to use `Dictionary` in order to set every employee's salary and i came up with that code Code ``` var employeeSalaryDictionary = new Dictionary<Employee, int>(); employeeSalaryDictionary.Add(new Employee { Name = "Chuck", Age = 37 }, 1000); employeeSalaryDictionary.Add(new Employee { Name = "Norris", Age = 37 }, 2000); employeeSalaryDictionary.Add(new Employee { Name = "Rocks", Age = 44 }, 3000); Employee employeeToFind = new Employee { Name = "Chuck", Age = 37 }; //or even Employee employeeToFind = new Employee { Name = "Chuck"}; //Always False... bool exists = employeeSalaryDictionary.ContainsKey(employeeToFind); ``` Employee Class ``` public class Employee { public string Name { get; set; } public int Age { get; set; } } ``` However as i commented out or as the topic title states, `.ContainsKey` always returns me `False` although i tried both ways as shown in the code.