Changing enumerations is fraught, but can be done to a limited extent. Consider:
public enum SomeColors
{
Black,
blue,
red
}
Code in another assembly compiled to use SomeColors.blue
will break if we do:
public enum SomeColors
{
Black,
Green,
blue,
red
}
Because it will have the value 1
compiled into it, which is now the value of SomeColors.Green
while SomeColors.blue
is now 2
.
Also, if we were to change the first to have the same capitalisation throughout to:
public enum SomeColors
{
Black,
Blue,
Red
}
Then running code would still work, but re-compiling would have compiler errors, as SomeColors.Blue
would not work. Also, Enum.Parse
would (in this case, depending on the case-sensitivity setting) work depending on which version of SomeColors was available to the running code.
However, adding values is not a breaking change. If we took the first and changed it to:
public enum SomeColors
{
Black,
blue,
red,
green
}
Then all existing code would be okay, but of course not know about green
unless found with Enum.Parse
.
So, if you are only going to add, and if you can depend upon nobody trying to Enum.Parse
a string from a more recent version, then it'll work.
The same holds true of const
values.
If you need to have values be changeable with versions, then you should use:
public static class SomeColors
{
public static readonly int Black = 0;
public static readonly int Blue = 1;
public static readonly int Red = 2;
}
As these are not constants, but fields assigned statically, they will be used from the class rather than compiled-in, and changes to the class will change what is used. Further safety in some cases can be given by making them properties rather than fields; most notably in that if you may want to make the calculated properties in the future, it would be a breaking change if they are currently fields but not if they are already properties.
If you want the values to be dynamic at runtime, then you need a class with an indexer that takes a string and returns an integer.