I have a dictionary where the keys are XYZ
objects and the values are boolean
. The XYZ class is from Autodesks API, so its not a class I made. I am attempting to check if a key exists in the dictionary.
My Problem: If the dictionary contains the key new XYZ(1,1,1)
and I go to check if the dictionary contains this key using myDictionary.ContainsKey(new XYZ(1,1,1)
is always returns false.
Why is this happening and how can I fix this? I think that the class XYZ
needs its Equals
method implemented but as I mentioned before I didn't make this class, its part of Autodesks API. Or am I doing something wrong?
Dictionary<XYZ, bool> prevPnts = new Dictionary<XYZ, bool>();
prevPnts[new XYZ(1,1,1)] = true;
// Always says the pnt doesnt exist?
if (prevPnts.ContainsKey(new XYZ(1,1,1)))
TaskDialog.Show("Contains");
else TaskDialog.Show("NOT Contains");
Solution using Konrads answer
class XYZEqualityComparer : IEqualityComparer<XYZ>
{
public bool Equals(XYZ a, XYZ b)
{
if (Math.Abs(a.DistanceTo(b)) <= 0.05)
return true;
return false;
}
public int GetHashCode(XYZ x)
{
int hash = 17;
hash = hash * 23 + x.X.GetHashCode();
hash = hash * 23 + x.Y.GetHashCode();
hash = hash * 23 + x.Z.GetHashCode();
return hash;
}
}
Dictionary<XYZ, bool> prevPnts = new Dictionary<XYZ, bool>(new XYZEqualityComparer());
Provide your own IEqualityComparer
to the dictionary, as it does not know how to compare XYZ
class (strictly speaking, it compares them by reference):
class XYZEqualityComparer : IEqualityComparer<XYZ>
{
public bool Equals(XYZ a, XYZ b)
{
return a.X == b.X && a.Y == b.Y && a.Z == b.Z;
}
public int GetHashCode(XYZ x)
{
int hash = x.X ^ x.Y ^ x.Z;
return hash .GetHashCode();
}
}
and then:
Dictionary<XYZ, bool> prevPnts = new Dictionary<XYZ, bool>(new XYZEqualityComparer());
Note: My implementation of GetHashCode
is only exemplary. Read What is the best algorithm for an overridden System.Object.GetHashCode? for better alternatives.