字典中的KeyNotFound异常(T)

时间:2010-03-14 17:09:01

标签: c# dictionary equals keynotfoundexception

我准备把头靠在墙上

我有一个名为Map的类,它有一个名为tiles的字典。

class Map
{
    public Dictionary<Location, Tile> tiles = new Dictionary<Location, Tile>();
    public Size mapSize;

    public Map(Size size)
    {
        this.mapSize = size;
    }
   //etc...

我暂时填写这本词典来测试一些东西..

public void FillTemp(Dictionary<int, Item> itemInfo)
    {
        Random r = new Random();
        for(int i =0; i < mapSize.Width; i++)
        {
            for(int j=0; j<mapSize.Height; j++)
            {
                Location temp = new Location(i, j, 0);

                int rint = r.Next(0, (itemInfo.Count - 1));

                Tile t = new Tile(new Item(rint, rint));

                tiles[temp] = t;
            }
        }

    }

和我的主程序代码

Map m = new Map(10, 10);
m.FillTemp(iInfo);
Tile t = m.GetTile(new Location(2, 2, 0)); //The problem line

现在,如果我在代码中添加一个断点,我可以清楚地看到我的地图类的实例(m)通过上面的函数填充了对,但是当我尝试使用GetTile函数访问一个值时:

    public Tile GetTile(Location location)
    {
        if(this.tiles.ContainsKey(location))
        {
            return this.tiles[location]; 
        }
        else
        {
            return null;
        }
    }

它总是返回null。同样,如果我在Map对象中查看并找到位置键,其中x = 2,y = 2,z = 0,我清楚地看到该值是FillTemp生成的Tile ..

为什么这样做?到目前为止,我对像这样的词典没有任何问题。我不知道它为什么返回null。再次,在调试时,我可以清楚地看到Map实例包含它所说的不存在的Location键... 非常令人沮丧。

任何线索?需要更多信息吗?

非常感谢帮助:)

3 个答案:

答案 0 :(得分:7)

您没有显示'Location'是什么,但如果它是一个类,则这是正常行为:通过比较引用来测试对象的Equality。因此,位置的不同实例将始终不相等,即使它们的内容相同。

对于Location类,最快的解决方法是override Equals()和GetHashCode()。然后将(重新)设计为不可变类(或者可能是不可变结构)是一个好主意。

答案 1 :(得分:1)

亨克是对的;当您在.Net中测试两个对象是否相等时,实际上是在询问“引用x是否指向与引用y相同的对象”。

所以,默认情况下:

Location a = new Location(2, 2, 0);
Location b = new Location(2, 2, 0);
Location c = a;

bool notEqual = ( a == b );  // false
bool equal = ( a == c );     // true

为了解决这个问题,你需要override the equality methods让你的Location对象比较相等的值 - 例如,Equals方法的主体可能会像我们这样结束:

return (this.x == that.x && this.y == that.y && this.z == that.z);

答案 2 :(得分:0)

谢谢大家!我真的很感激!

我将Location设置为值类型,现在它正常工作。

我很抱歉没有发布整个代码,但我觉得没有必要,并且假设读者可以认为该位置是一个带有x,y,z int值的简单类。

由于你们所有人的缘故,我学到了许多新东西,而且我对这种(通常)精彩语言的理解因此而更加出色:o)

小心,