6

I stumbled upon a code where my colleague has recently modified an existing enum and added another enum just before the last enum, I am guessing he may have done this because the last enum was None(we are not in the same timezone to discuss).

My worry is if any code in the solution tries to fetch the integer value of None Enum(which I couldn't find anywhere luckily, but what about some code tries to do in future), then this will potentially produce wrong results.

Wouldn't it be safe to?

  1. Either Add Enum in the last
  2. Or associate an integer value against each enum so that ordering issue can be resolved?

Please throw some light.

Update: In one of the SO question, I read @Marc Gravell mentioning that inserting in the middle is dangerous, did I understand him correctly? Please see https://stackoverflow.com/a/12716043/2719527

Vivek Shukla
  • 767
  • 6
  • 21
  • If you have never used some enum item in the whole code base, how can you break the code by pushing this item down by one (if this is last item)? – T.S. Apr 26 '18 at 20:25
  • 1
    @T.S. the compiler autogenerates a backing value - if you cast it the value will be different if you add a new value between existing ones. – Daniel A. White Apr 26 '18 at 20:25
  • Yes, your two suggested options are safer in cases where you have code that expects certain enum values to have specific integer values associated with them, but that's kind of a bad practice also. In general, your colleague's change should be ok. – Rufus L Apr 26 '18 at 20:36
  • @DanielA.White I understand that. But if he said, it is not used then it can't be broken. There are many variables. Is code used as third-party code? etc – T.S. Apr 26 '18 at 20:36
  • "None" should really always be the _first_ item, since automatically filled in empty variable of that type (like, class variables or arrays elements) will be initialized to the first value (the one with integer value 0). That said, unless the enum has specific numbers defined in it, it should never, _ever_ be used as or compared to an integer. – Nyerguds Apr 26 '18 at 21:38

2 Answers2

5

There is no problem with adding new values at any place in enum list, because when the code with new enum in place is recompiled, the compiler figures out proper ordinals for all values.

There would be a problem if instances of the old enum were persisted, say, to a database. In this case assigning values explicitly would be a better alternative, because stored values would not be changed by a recompile, and would translate to incorrect values on retrieval.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • Some Enums in my project has a pretty long list, like 20 members what not, assigning a value wouldn't be little too much ? – Vivek Shukla Apr 26 '18 at 20:37
  • 2
    @Vivek_Shukla unless you do something like if (someEnum == 1) or its stored in the DB. You will be fine without a number assigned – Steve Apr 26 '18 at 20:39
  • @Vivek_Shukla Both Marc's points are applicable to any `enum` modifications, in the middle or at the end. His second point, about serialization, is identical to what I said about persisting an `enum` value. – Sergey Kalinichenko Apr 26 '18 at 20:46
  • @dasblinkenlight My interpretation of his comment was that it can be really dangerous if there is code which is using its integer value, i.e. public enum Status { Good, Fair, Poor } (UInt16)Status.Good. Please throw some light on the DB part. – Vivek Shukla Apr 26 '18 at 21:01
  • 1
    It's dangerous if you're storing enum values in a database, and then the enum changes in such a way that the values are now associated with different enum names. If you found that `Something.Status == Poor` and you saved that to the database as `Something.Status = 2`, then later you insert a new value before `Poor` in your `enum` definition, that historical record, when pulled from the database and presented in some UI, will look like `Something.Status = NewInsertedStatus` – Rufus L Apr 26 '18 at 21:13
2

If you are concerned about breaking changes, do either thing that you suggest. The safest is always to assign a value to each member, that way it is explicit and you don't depend on the compiler generating something for you.

Daniel A. White
  • 187,200
  • 47
  • 362
  • 445