Breaking Changes: .Net Enums an often overlooked dangerzone

Hierarchical Testing – When Can I Test It?
November 25, 2017
The discussion of complex increases in complexity….
December 23, 2017

Breaking Changes: .Net Enums an often overlooked dangerzone

It has been a while since there was a post in this series, but just today I was involved in a set of discussions related to adding new values to an already published (and widely consumed) enum; so I figured it was a good topic for a posting.

To start, lets consider a very simple enum:

enum ImportantLetters { a, b ,h, i}

At some point after publication, “c” becomes an ImportantLetter, so there is a desire to add it to the declared enum. The most natural place would be to add it between “b” and “h” giving:

     enum ImportantLetters { a, b ,c, h, i}

Seems safe enough…. But what if someone had previously written

     static int Ordinal(ImportantLetters x)
     {
        List<ImportantLetters> set = new List<ImportantLetters>();
        foreach (ImportantLetters s in Enum.GetValues(typeof(ImportantLetters)))
           set.Add(s);
        return set.IndexOf(x);
     }

Existing code which returned a value of 2 when passed “h” will now return 3 !!!!!    Any decisions or calculations which were based on the return value will now be wrong.

Unfortunately, with the .Net implementation of enum’s there is no way to avoid this. Some options might be viable if enums supported inheritance along with operators and co/contra variance. Alas, they do not.

The root of the problem is that the initial set of values was not an immutable (never changing) set of values. It would require a different implementation (rather than enums) to allow for proper representation of a set of values with the ability to safely add new values without the potential for breaking code.

Of course there is always be the need to make breaking chances, despite one’s desire to adhere to SOLID (and other) design and implementation principles. But we are fallible, and there will be occurrences. The key element is to recognize them, and deal with them accordingly. If one is making an effort to follow Semantic Versioning [SemVer], then a breaking change requires an increment in the major version number.

5 Comments

  1. David Maiden says:

    I agree with Daniel however to be clear I assign values of 10, 20, 30 etc. Allows plenty of room for additions between two entries and keeps the order!

  2. I totally agree with Daniel. Assing values.

    Your problem is not that the initial set of values was not an immutable. Your problem lies within the Ordinal function and the meaning of your enum. It seems you’re using your enum as a simple list of values. Why would you want a enum for that.

    Enums can be used for modes or states or something like that. Given a certain value your program can respond to it. Adding a new mode or state probably also means that your program needs a new way to handle a different value.

Leave a Reply

Your email address will not be published. Required fields are marked *

FREE CONSULTATION
Loading...