To Enum or Not to Enum

Posted by Mortimer452@reddit | ExperiencedDevs | View on Reddit | 203 comments

Something I always struggle with in architecture/design is the proper use of Enums for object members that have a distinct set of possible values. Stack is C#/MSSQL/Blazor if that matters.

A simple example of this would be an Customer object with a property MembershipStatus. There's only four possible values: Active, Trial, Expired, Cancelled.

There's two choices here:

Define MembershipStatus as an integer enum: - (pro) Normalized, in the back-end the DB column is an integer - (pro) MembershipStatus is strongly typed in code and is therefore constrained to those four values, they pop-up in autocomplete and accidental assignment of invalid values is impossible without a runtime error - (pro) I can just use .ToString in the UI to show a "friendlier" name instead of the int values - (con) On the DB side, it's a meaningless int value. Anyone doing stuff in the DB layer (stored procs, reporting, custom queries, exports, etc.) have to keep track of these and roll their own logic for display purposes (replacing "1" with "Active", etc.) They could also assign an invalid int value and nothing would break. - (pro/con) I could create a MembershipStatus table with an FK to Customers.MembershipStatus to eliminate the above issue (SQL people can JOIN to this table for "friendly" names, FK constraint prevents invalid values) but now every time I add another value to my Enum I have to remember to add it in the lookup table as well.

Define MembershipStatus as a string: - (pro) Non-ambiguous and easy to read everywhere - (pro) I can define the possible values as Consts in code to make sure they are kept consistent in code - (con) For the DBA in me this just "feels wrong" to have a freeform text field containing what really should be a lookup table to maintain integrity - (con) Uses more storage on the DB side (varchar versus 4-byte int) - (con) Anything using this on the C# side is just a string value, not strongly typed, so it's possible to assign invalid values without generating any errors

Anyway, sorry for the long post, hopefully at least a few here have dealt with this dilemma. Are you always one or the other? Do you have some criteria to decide which is best?