Search code examples
c#enums

Does using System.Enum as a variable type have a downside compared to using a direct reference to the enum?


Im working on a game with RPG elements, and am currently doing an ability system. While trying to figure out how I want it to work I stumbled on System.Enum, something I havent used before but it seems very powerful to be able to store any enum I want. I was wondering if it has a downside? Does the compiler still do a cast or something behind the scenes to figure out what type of enum it is? Dont know how to figure it out by myself and had a hard time finding an answer, or atleast one I could understand.

public class TestingStuff
{
    private void ExampleOne()
    {
        System.Enum anyEnum = Vehicle.Car;
        switch (anyEnum)
        {
            case Vehicle.Car:
                //do stuff
                break;
        }
    }

    private void ExampleTwo()
    {
        Vehicle thisEnum = Vehicle.Car;
        switch (thisEnum)
        {
            case Vehicle.Car:
                //do stuff
                break;
        }
    }

    private enum Vehicle
    {
        Car
    }
}

So in this example, would ExampleOne() and ExampleTwo() perform the same way? In the game I will have multiple AI characters that would have to do multiple ability checks in this manner to see what ability best suits the situation. I dont expect to reach more than maybe 10-20 of these calls in any single frame so I dont think its an issue either way, but it still got me curious and I would like to learn more.


Solution

  • Casting to System.Enum causes a boxing operation (as pointed out in the comments) which has a slight overhead and can mess with comparison operations-- two boxed values of Vehicle.Car, for example, could evaluate to false, because the boxed objects are different references.

    Enum a = Vehicle.Car;
    Enum b = Vehicle.Car;
    Console.WriteLine(a == b); //outputs False
    

    If you want to have an efficient way to store any enum, you can use an int, which costs no overhead. This is because enums are actually stored as integers under the covers by default (they can also be stored as longs or other types if you choose to).

    private void ExampleThree()
    {
        int thisEnum = (int)Vehicle.Car;
        switch ((Vehicle)thisEnum)
        {
            case Vehicle.Car:
                //do stuff
                break;
        }
    }
    

    Be warned though. Some consider overuse of enums a code smell.