[英]System.Collections.Generic.KeyNotFoundException : The given key 'Item' was not present in the dictionary
I'm trying to implement a basic sprite game in C#.我正在尝试用 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.我正在测试两个字典是否彼此相等,并且我在精灵类中的 Containskey() 和 Equals 函数有问题。
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;
}
}
else
{
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;
}
else
{
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;
}
else
{
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.在这里,dictionary.Equals() 函数正常工作,但我的 testSprite 没有一个与我预期的 Sprite 匹配,因为当我使用一个项目时,它不会从 testSprite 库存中正确递减。 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. takeItem 函数调用 hasItem 函数来检查字典/库存是否有一个项目,它总是返回 false 因为 containskey 函数总是返回 false 即使我知道字典在打印出内容时包含键的事实字典到控制台。
Below is the Item.cs file.下面是 Item.cs 文件。
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));
}
public override bool Equals(Object obj)
{
//Check for null and compare run-time types.
if ((obj == null) || ! this.GetType().Equals(obj.GetType()))
{
return false;
}
else
{
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.我怀疑 GetHashCode 函数之一有问题,但我不完全确定如何修复它,因此感谢任何帮助。 Thanks谢谢
First of all, Item class should implement IEqualityComparer<Item>
.首先, Item 类应该实现IEqualityComparer<Item>
。 Also, ==
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])
after implementing IEqualityComparer.此外, ==
用于引用相等(对于引用类型,如 Item 是一个类),但似乎您在这里需要的是结构相等 - 所以inv[entry.Key] == inv2[entry.Key]
将失败- 在实现 IEqualityComparer 后尝试inv[entry.Key].Equals(inv2[entry.Key])
。
Info on IEqualityComparer<T>
: https://docs.microsoft.com/en-us/dotnet/api/system.collections.generic.iequalitycomparer-1?view=net-5.0关于IEqualityComparer<T>
: https : IEqualityComparer<T>
= IEqualityComparer<T>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.