添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

System.Collections.Generic.KeyNotFoundException : The given key 'Item' was not present in the dictionary

Ask Question

I'm trying to implement a basic sprite game in C#. I'm testing to see if two dictionaries are equal to each other and I'm having an issue with Containskey() as well as my Equals function in the sprite class.

public class Sprite
    private Point p;
    private uint Horiz;
    private uint Vert;
    private uint Health;
    private uint Shield;
    private Dictionary<Item, int> inv;
    private string[] QuickSlots;
    /* Default constructor
     * set all values to 0
    //string[] empty;
    //string [] mt;
    public Sprite()
        Point newpoint = new Point();
        newpoint.SetX(0);
        newpoint.SetY(0);
        newpoint.SetZ(0);
        p = newpoint;
        Horiz = 0;
        Vert = 0;
        Health = 0;
        Shield = 0;
        inv = null;
        QuickSlots = null;
    public override int GetHashCode()
        return (int)(p.GetX() ^ (p.GetY() << 8) ^ (p.GetZ() << 16) ^
            Horiz ^ (Vert << 9) ^ 
            (Health << 18) ^ (Shield << 25));
    public bool DictionaryEquals(Dictionary<Item, int> inv2)
        foreach(KeyValuePair<Item, int> entry in inv2)
            if(inv.ContainsKey(entry.Key)) //(inv[entry.Key] == inv2[entry.Key]))
                if((inv[entry.Key] == inv2[entry.Key]))
                    continue;
                else{
                    return false;
                return false;
        return true;
    public override bool Equals(Object obj)
        //Check for null and compare run-time types.
            if ((obj == null) || ! this.GetType().Equals(obj.GetType()))
                return false;
                Sprite s = (Sprite) obj;
            //   this.PrintInventory();
                s.PrintInventory();
            return 
                ((p.Equals(s.p)) &&
                (inv.Equals(s.inv)) &&
                //(QuickSlots == s.QuickSlots) &&
                (Horiz == s.Horiz) &&
                (Vert == s.Vert) &&
                (Health == s.Health) &&
                (Shield == s.Shield));
    public bool HasItem(string item)
        return inv.ContainsKey(StringtoItem(item, this));
    public void TakeItem(string item)
        Console.WriteLine("Does this even work\n");
        if(HasItem(item))
            Console.WriteLine("Does this even work2\n");
            int x = inv[StringtoItem(item, this)] - 1;
            if(x > 0)
                Console.WriteLine("Does this even work3\n");
                inv[StringtoItem(item, this)] = x;
                Console.WriteLine("Does this even work4\n");
                inv.Remove(StringtoItem(item, this));

Here, the dictionary.Equals() function works correctly but none of my testSprites match my expected Sprites because when I use an item, it doesn't decrement correctly from the testSprite inventory. The takeItem function calls the hasItem function to check if a dictionary/inventory has an item and it always returns false because the containskey function is always returning false even though I know for a fact that the dictionary contains the key when print out the contents of the dictionary to the console.

Below is the Item.cs file.

public class Item
        private string name;
        protected Sprite holder;
        public Item(string n, Sprite h)
        //, int hc, int sc, int ec,
        //      uint mh, uint ms, bool i, uint s, uint md)
                name = n;
                holder = h;
        public string GetItemName()
            return name;
        public override int GetHashCode()
        return (int)(name.GetHashCode() ^ (holder.GetPoint().GetX() << 8) ^ (holder.GetPoint().GetY() << 16) ^ 
            (holder.GetPoint().GetZ() << 16) ^
            holder.GetHoriz() ^ (holder.GetVert() << 9) ^ 
            (holder.GetHealth() << 18) ^ (holder.GetShield() << 25));
        //Check for null and compare run-time types.
            if ((obj == null) || ! this.GetType().Equals(obj.GetType()))
                return false;
                Item i = (Item) obj;
            return 
                ((name == i.name) &&
                (holder.Equals(i.holder)));

I suspect that something is wrong with one of the GetHashCode functions but I am not entirely sure how to fix it so any help is appreciated. Thanks

== is used for referential equality (for reference types, like Item which is a class), but seems that what you need here is structural equality - so inv[entry.Key] == inv2[entry.Key] will fail - try inv[entry.Key].Equals(inv2[entry.Key]) (you did override Equals and GetHashCode already according to your structural equality logic). You could have also make public class Item : IEquatable<Item> as a bonus :)

Sure, let me know the results! I would suggest you can also edit the question to include the code calling these classes. – Yom B Oct 18, 2021 at 23:09 I ended up including the private string name in my gethashcode function and that got rid of the error. Thank you though – blub_9 Oct 21, 2021 at 18:56

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.