- Home /
Is it safe to use GameObject as a Dictionary key?
Is it safe to use GameObjects or Components that might be destroyed at any time as keys to Dictionary
?
If not, what should we use instead? Object.GetInstanceID()
? Is it guaranteed that those IDs are never reused in a single run of the program (I'd assume so but the docs are not 100% clear)? And how do we then detect whether the corresponding object has been destroyed?
Background
Unity makes some questionable changes to C#:
operator== is overridden for
UnityEngine.Object
Unity has a mechanism to check that destroyed objects' methods aren't accessed.
I presume Dictionary
is internally allowed to call GetHashCode
and operator==
on its keys at any time.
Answer by Bunny83 · May 06, 2018 at 12:31 AM
No there shouldn't be any issues with the Dictionary, That's because as you know a C# managed object can not be destroyed, only the native part. Your managed object will turn into a fake null object but that shouldn't cause any problems. The UnityEngine.Object class actually overrides GetHashCode and simply returns the instance ID of the gameobject. However this ID is stored in the managed object itself and it stays the same when you destroy the object. So since the hashcode stays the same from the Dictionary point of view it only deals with an object reference.
The overloaded == operator of UnityEngine.Object is not used inside the Dictionary since operators are statically linked. So inside the generic Dictionary it will use the default == operator. The Dictionary actually performs a null check on the key when you get / set a value. Since the managed object is still a valid C# object and the == operator actually checks the real reference it just works the same.
Unity also overrides the virtual Equals method to implement the fake null behaviour. Though a direct comparison sill works the same so go.Equals(go)
will return true even for fake null objects.
Note that this actually holds true for any UnityEngine.Object derived type which covers nearly every object type that is shipped with the Unity engine (GameObject, Component, Mesh, Material, ...)
Your answer
Follow this Question
Related Questions
gameobject has been destroyed you are still trying to access it 2 Answers
Allocating Game Object name dynamically using Find 0 Answers
[UNSOLVED] Object reference not set to an instance of an object 0 Answers
Set gameobject to null in a function 1 Answer
Null reference when calling a method from another script 1 Answer