Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dictionary Says Key Doesn't Exist When It Does

Tags:

c#

autodesk

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());
like image 993
Mack Avatar asked Feb 16 '26 04:02

Mack


1 Answers

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.

like image 150
Konrad Kokosa Avatar answered Feb 18 '26 18:02

Konrad Kokosa



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!