Wibble
Wibble

Reputation: 89

KeyNotFoundException: The given key was not present in the dictionary

I am sorry if this question is being asked because i missed something incredibly basic.

I am getting KeyNotFoundException: The given key was not present in the dictionary from Unity for a search for a Dictionary Key. Yet throughout my (still quite small) project i am successfully using MapLocation in other Dictionarys as a Key

I have stripped the code down to basics.

public class SpriteManager : MonoBehaviour {

Dictionary<MapLocation, GameObject> SpriteDictionary;

void Start(){
    SpriteDictionary = new Dictionary<MapLocation, GameObject>();

    for (int x = 0; x < 10; x++) {
        for (int y = 0; y < 10; y++) {
            //Create Location Data
            MapLocation mLoc = new MapLocation(x, y);

            //Create GameObjects
            GameObject go = new GameObject();

            SpriteDictionary.Add(mLoc, go);
        }
    }
    MapLocation mTest = new MapLocation(0,1);
    Debug.Log("Dictionary entry exists?: " + SpriteDictionary.ContainsKey(mTest));
}

At the end the mTest of MapLocation(0,1) Debug line is giving me a false.

Here is the MapLocation code for completion.

using UnityEngine;
using System.Collections;

[System.Serializable]
public class MapLocation {

    public int x;
    public int y;

    public MapLocation(){}

    public MapLocation(int x, int y){
        this.x = x;
        this.y = y;
    }
}

Upvotes: 2

Views: 2353

Answers (2)

Pooven
Pooven

Reputation: 1764

deyu note is correct, when using custom types as the key in a dictionary, you must define GetHashCode and Equals. For interest, I've include alternative hashing algorithms.

The existing Point class calculates the hash as follows:

public override int GetHashCode()
{
  return this.x ^ this.y;
}

Using ReSharper code completion:

public override int GetHashCode()
{
  unchecked
  {
    return (this.x * 397) ^ this.y;
  }
}

Upvotes: 1

deyu
deyu

Reputation: 329

You have to override GetHashCode() and Equals(object obj) of MapLocation, for example:

public override bool Equals(object obj)
{        
    MapLocation m = obj as MapLocation;
    return m == null ? false : m.x == x && m.y == y;
}

public override int GetHashCode()
{
    return (x.ToString() + y.ToString()).GetHashCode();
}

Inside YourDictionary.ContainsKey(key) and YourDictionary[key], use GetHashCode() and Equals(object obj) to judge equivalent. Reference

Upvotes: 4

Related Questions