Enum Serialization

Enums are an interesting type in programming languages.  From a compiler's perspective they are type safe symbols that have corresponding int values.  The thing programmers need to be careful of however is that from a coding standards standpoint the values of the enum should not matter.

For example in the code below the actual value of the enum should not effect the code, even being used as a mask programmers using the enum should not need to know the value of the enum.

1
2
3
4
5
6
7
COLOR_TYPE GetColorTypeByMask( int mask)
{
    COLOR_TYPE color = COLOR_RED;
    if( maskValue | MASK_ALWAYS_GREEN)
    	color = COLOR_GREEN;
    return color;
}

So this brings up the question of when serializing enums, should we really be serializing the value?  What happens if we remove a value from an Enum declaration?

1
2
3
4
5
6
7
8
public enum PrizeType_E
{
    PT_None, //0
    PT_Diamonds, //1
    PT_Silver, //2
    PT_Gold, //3,
    PT_Max //4
}

If we remove PT_Gold as a prize type above, this means anything serialized as PT_Gold's value (3) will equal PT_Max when it is deserialized, which could certainly cause a lot of issues.  So what is the solution?

The solution is to find a way to serialize the name of the enum values, not the values themselves.  A simple way to do this would be to do something like this:

1
2
3
4
5
6
7
enum EnumType
{
    EnumValue1,
    EnumValue2,
    EnumValue3
}
const char* EnumTypeStrings[] = {"EnumValue1", "EnumValue2","EnumValue3"};

However this is a duplication of data and would make editing enums dangerous if someone forgot to modify the const char* array too.  The answer tends to be we need to make a macro to handle this case, but the specific macro depends on the compiler, language and even engine you are using.

However in C# this is much easier, Enum is a class with the following functions:

1
2
public static string GetName(Type enumType, Object value);
public static bool TryParse<TEnum>(string value, out TEnum result);

Using these functions it is very easy at run-time to get the string name of an enum value and deserialize it as well.

Over the next few weeks I'll visit how I've handled this is different languages and linking them here:

For C++ compilers where enum forward declaration is allowed.

For C/C++ compilers where enum forward declaration is not allowed.

How to handle Enum serialization in Unity