When you’re creating a new base enum consider using multiples of 10 for values. This makes extending enums a lot easier, especially if it indicates some kind of status. Those of you who once programmed in BASIC, or any other language with line numbers, can probably guess where I’m going with this. My apologies for any painful flashbacks this may trigger.
Suppose you’re creating an interface with another system. It turns out you need a new enum, MessageStatus. Values are assigned automatically, so Received = 0, Started = 1, Processed = 2, and Archived = 3.
Of course, at some point you need to do different things depending on the status. Let’s say you have written this function.
boolean isOpen(MessageStatus _status)
{
return _status < MessageStatus::Processed;
} |
boolean isOpen(MessageStatus _status)
{
return _status < MessageStatus::Processed;
}
This is a simple way to indicate at which point the message is no longer considered open. Standard Dynamics Ax contains similar examples, e.g. with the inventory status (StatusIssue and StatusReceipt).
Your message handling system goes live and works perfectly. Users are happy, birds are singing, the sun is shining.
After a while users decide they need a verification step before moving to Started. You extend the enum and end up with MessageStatus::Verified = 4. And now things are broken. Verified messages aren’t handled correctly.
You need to check all places where the status is used. You run across the isOpen() method and change it.
boolean isOpen(MessageStatus _status)
{
return _status < MessageStatus::Processed || _status == MessageStatus::Verified;
} |
boolean isOpen(MessageStatus _status)
{
return _status < MessageStatus::Processed || _status == MessageStatus::Verified;
}
Not so readable anymore but it works. For now. Things can get out of hand quickly if more than 1 status is added.
This could have been avoided from the start if the enum elements were assigned specific values.
Received |
10 |
Started |
20 |
Processed |
30 |
Archived |
40 |
Adding a new step somewhere in the middle is easy. Create Verified with value 15 and isOpen() doesn’t need to be modified.
Now you may think this is a great idea (It is. Thank you.) but don’t go changing all your enums now. Changing values means you also need to modify all fields that use it, as they still contain the old numbers. This is the reason you need to think about enum values in advance. Once a system is deployed, it’s usually better to leave these things as they are to avoid even more trouble.
In practice starting with multiples of 10 is enough to deal with any reasonable modifications. I have yet to run into a situation where a gap of 9 values isn’t enough. Unfortunately standard Dynamics Ax enums have continuous values starting at 0. If you need to insert something in between you still have to check all code that covers a range of enum elements.