KeyNotНайдено исключение в словаре (из T) - PullRequest
2 голосов
/ 14 марта 2010

Я почти готов биться головой об стену

У меня есть класс с именем Map, в котором есть словарь с именем tile.

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

ВСЕГДА возвращает ноль. Опять же, если я просматриваю объект Map и нахожу ключ Location, где x = 2, y = 2, z = 0, я ясно вижу значение Tile, сгенерированное FillTemp ..

Почему он это делает? У меня не было проблем с таким словарём, как этот. Я понятия не имею, почему он возвращает ноль. и снова, при отладке я могу Ясно увидеть, что экземпляр Map содержит ключ Location, который говорит, что он не ... очень расстраивает.

Есть какие-нибудь подсказки? Нужна дополнительная информация?

Помощь будет принята с благодарностью:)

Ответы [ 3 ]

7 голосов
/ 14 марта 2010

Вы не показываете, что такое «Location», но это нормальное поведение, если это класс: объекты проверяются на равенство путем сравнения ссылок. Таким образом, различные экземпляры Location всегда будут неравными, даже если их содержимое одинаково.

Самое быстрое решение - переопределить Equals () и GetHashCode () для класса Location. И тогда будет хорошей идеей (пере) спроектировать его как неизменяемый класс (или, может быть, неизменную структуру).

1 голос
/ 14 марта 2010

Хенк прав; когда вы проверяете, равны ли два объекта в .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);
0 голосов
/ 14 марта 2010

Спасибо всем! Я действительно ценю это!

Я превратил Location в тип значения, и теперь он работает просто отлично.

Прошу прощения, что не опубликовал весь код, но я не чувствовал, что это необходимо, и предположил, что читатель может предположить, что это простой класс со значениями x, y, z int.

Я узнал много нового из-за всех вас, и мое понимание этого (как правило) замечательного языка больше из-за него: o)

Береги себя,

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...