C# Enums – Compatibility with String Constants

ccompatibilityenumserialization

I was recently told that using Enum:

public enum TaskEndState { Error, Completed, Running }

may have compatibility/serialization issues, and thus sometimes it's better to use const string:

public const string TASK_END_STATE = "END_STATE";
public const string TASK_END_STATE_ERROR = "TASK_END_STATE_ERROR";
public const string TASK_END_STATE_COMPLETE = "TASK_END_STATE_COMPLETE";
public const string TASK_END_STATE_RUNNING = "TASK_END_STATE_RUNNING";

Can you find practical use case where it may happen, is there any guidelines where Enum's should be avoided?

Edit:
My production environment has multiple WFC services (different versions of the same product). A later version may/or may not include some new properties as Task end state (this is just an example). If we try to deserialize a new Enum value in an older version of a specific service, it may not work.

Best Answer

You don't say how exactly are you serializing the Enum, which is important here. I'm going to assume that you serialize it as the underlying integral value. In that case, your current code indeed has a versioning issue, if you add a new value into the middle of the Enum.

For example, in your current code, Error is 0, Completed is 1 and Running is 2. Now imagine you changed the code to:

public enum TaskEndState { Error, Timeout, Completed, Running }

Suddenly, what you saved as Running (old 2) will be read as Completed (new 2), which is not correct.

The best way to deal with this is to explicitly specify the numeric values for each enum member and never change them. You can add new values laster, but they have to have a new integer value. For example, the original:

public enum TaskEndState { Error = 0, Completed = 1, Running = 2 }

And the modified version:

public enum TaskEndState { Error = 0, Timeout = 3, Completed = 1, Running = 2 }