Dictionary.ContainsKey return False, but a want True
namespace Dic
{
public class Key
{
string name;
public Key(string n) { name = n; }
}
class Program
{
static string Test()
{
Key a = new Key("A");
Key b = new Key("A");
System.Collections.Generic.Dictionary<Key, int> d = new System.Collections.Generic.Dictionary<Key, int>();
d.Add(a, 1);
return d.ContainsKey(b).ToString();
}
static void Main(string[] args)
{
System.Console.WriteLine(Test());
}
}
}
What should I change to get true?
Solution 1:
You want true - but a and b are different objects.
You need to override GetHashCode and Equals on class Key
public class Key
{
string name;
public Key(string n) { name = n; }
public override int GetHashCode()
{
if (name == null) return 0;
return name.GetHashCode();
}
public override bool Equals(object obj)
{
Key other = obj as key;
return other != null && other.name == this.name;
}
}
Solution 2:
It would probably help if you override Key.GetHashCode and Key.Equals.
In Key
:
public override bool Equals(object obj)
{
var k = obj as Key;
if (k != null)
{
return this.name == k.name;
}
return base.Equals(obj);
}
public override int GetHashCode()
{
return this.name.GetHashCode();
}
Solution 3:
If you do not have the ability to override equality operators/Equals/GetHashCode as others have mentioned (as in, you do not control the source code of the object), you can provide an IEqualityComparer<Key>
implementation in the constructor of the dictionary to perform your equality checks.
class KeyComparer : IEqualityComparer<Key>
{
public bool Equals(Key x, Key y)
{
return x.Name == y.Name;
}
public int GetHashCode(Key obj)
{
return obj.Name.GetHashCode();
}
}
As it stands, your Key is a reference object, so equality is only determined on reference unless you tell the world (or the dictionary) otherwise.