Enumerations as Dictionary Keys
From Shawn Hargreaves:
- "If you use an enum type as a dictionary key, internal dictionary operations will cause boxing. You can avoid this by using integer keys, and casting your enum values to int before adding them to the dictionary."
What this means is that if you declare a dictionary, say for input, like this:
Dictionary<PlayerIndex, GamePadState> states
each time you access that dictionary, you will see boxing and unboxing from your enumeration.
There is thorough explanation thanks to Vojislav Stojkovic:
- "In other words, the boxing happens because my enum doesn't implement the IEquatable interface. The funny thing is that Int32 value type implements IEquatable, as does every other primitive numeric type. Yet enums don't. When you stop to think of it, it sounds logical: the Enum value type can't implement IEquatable because that would theoretically allow you to compare any enum to any other enum and obtain bogus results."
In the end, Vojislav also provides advice for how to use enumerations as dictionary keys while avoiding the boxing/unboxing cost:
- "To sum it up, for each enum type you intend to use as a dictionary key, you'll have to write your implementation of IEqualityComparer and pass it to Dictionary constructor."
(For an example of how to do this, see Nick Gravelyn's .NET Misconceptions Part 1 blog post, which provides a simple, easy to use IEqualityComparer implementation for the PlayerIndex enum that can easily be modified for any enum you want to use as a key.)
Keep that in mind as these unnecessary garbage collections can wreak havoc on Xbox 360 games (due to the Xbox 360's garbage collector being less than stellar) and can also introduce jerkiness to your PC games.