字典中的 KeyNotFound 异常(T)

发布于 2024-08-25 11:05:34 字数 1521 浏览 8 评论 0原文

我正准备用头撞墙,

我有一个名为 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 处的 Location 键,我清楚地看到该值是 FillTemp 生成的 Tile。

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

有什么线索吗?需要更多信息吗?

非常感谢您的帮助:)

I'm about ready to bang my head against the wall

I have a class called Map which has a dictionary called tiles.

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

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

I fill this dictionary temporarily to test some things..

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;
            }
        }

    }

and in my main program code

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

now, if I add a breakpoint in my code, I can clearly see that my instance (m) of the map class is filled with pairs via the function above, but when I try to access a value with the GetTile function:

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

it ALWAYS returns null. Again, if I view inside the Map object and find the Location key where x=2,y=2,z=0 , I clearly see the value being a Tile that FillTemp generated..

Why is it doing this? I've had no problems with a Dictionary such as this so far. I have no idea why it's returning null. and again, when debugging, I can CLEARLY see that the Map instance contains the Location key it says it does not...
very frustrating.

Any clues? Need any more info?

Help would be greatly appreciated :)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

没有伤那来痛 2024-09-01 11:05:34

您没有显示“位置”是什么,但如果它是一个类,这是正常行为:通过比较引用来测试对象的相等性。所以不同的 Location 实例总是不相等的,即使它们的内容是相同的。

最快的修复方法是覆盖 Equals() 和 Location 类的 GetHashCode()。然后,将其(重新)设计为不可变类(或者可能是不可变结构)是一个好主意。

You don't show what 'Location' is but this is normal behavior if it is a class: objects are tested for Equality by comparing the references. So different instances of Location will always be unequal, even if their content is the same.

The quickest fix is to override Equals() and GetHashCode() for the Location class. And then it is a good idea to (re)design it as an immutable class (or maybe immutable struct).

九歌凝 2024-09-01 11:05:34

亨克是正确的;当您测试 .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

要解决此问题,您需要 覆盖 Location 对象的相等方法以比较值是否相等 - 例如,Equals 方法的主体可能是我们的结局是这样的:

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

Henk is correct; when you test to see if two objects are equal in .Net, you're actually asking if "reference x is pointing to the same object as reference y".

So, by default:

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

To get around this, you need to override the equality methods for your Location object to compare the values for equality - the body of your Equals method, for example, might end us as something like:

return (this.x == that.x && this.y == that.y && this.z == that.z);
画中仙 2024-09-01 11:05:34

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

我将位置设置为值类型,现在它工作得很好。

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

因为你们所有人,我学到了很多新东西,而且我对这种(通常)美妙的语言的理解也因为它而更加深刻:o)

保重,

Thank you everyone! I really appreciate it!

I made Location into a value type and now it's working just fine.

I'm sorry for not posting the whole code, but I didn't feel it was necessary and assumed that the reader could assume that location was a simple class with x,y,z int values.

I learned many new things because of all of you and my understanding of this (generally) wonderful language is greater because of it :o)

Take care,

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文