KeyNot Найдено исключение в словаре (из T)

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

У меня есть класс с именем Map, в котором есть словарь, который называется плитки.

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 ответа

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

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

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

Всем спасибо! Я очень ценю это!

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

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

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

Береги себя,

Другие вопросы по тегам