Dictionary
を受け取るコンストラクターを使用しておらず、クラスIEqualityComparer<T>
にカスタムの等価性を実装していません。Employee
そのため、現在、辞書は従業員を参照によって比較しています。あなたnew
が従業員の場合、たとえば名前が同じであっても、参照先が異なります。
おそらく、ここで最も簡単な方法はIEqualityComparer<Employee>
、等価比較に使用するメンバーを選択して辞書のコンストラクターに渡すことができる独自の を実装することです。
[編集] 約束どおり、スニペット:
//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;
}
}
}
その後:
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!
完全を期すために、名前のみの比較子を次に示します (これも 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);
}
}
しかし、お気づきのように、ディクショナリを作成するときにキー比較に使用する比較子を決定する必要があります。後から変えられない…