Coding style: simple defensive code style for C# enums

As I start 2017, on the back of a recent project-related win (successful deployment of an high profile, high pressure project subject to rapidly evolving and loosely defined requirements, deployed into a world leading software vendor client – damn its nice to have a win!), I’m finally able to take a bit of a step back, and reflect a bit on how things went, what worked well, and especially, what gave the best bang for buck.

One absolutely *key* point, that I will hopefully address again soon in a future post, was being able to largely turn off my previous problematic analysis-paralysis-“it-has-to-be-*right*-from-the-start” pipe dreams, and instead approaching my work with an almost utter indifference to the idea that code would be written, revised, discarded, rewritten, revised, discarded… In the space of a few short months, I would utterly recreate the entire code base several times over, managing to set my ego aside in the (admittedly, necessary and admirably enforced by my teammates) ruthless pursuit of deadlines and client satisfaction.

On reflection though, I have noticed that almost disappointingly to my inner nerd, almost nothing “sexy” or “cool” was required to get results. Instead, I tried to apply a fairly simple process:

  • As much as possible, avoid strict patterns that would result in excessive boilerplate (for example, Ayende’s old posts on anti-repository thinking influenced me here, and basically anything from Mythz from ServiceStack that emphasised results over dogma). Instead, I relied on a set of brutally simple, easily implemented and yet widely applicable helper methods (in particular, to supplement data access functionality to the Dapper framework for type-safe CRUD operations);
  • Implement sweeping end-to-end integration-style test cases, to capture the main/typical/key functionality features; and
  • As much as possible, code warily and defensively, so that errors bite me early, and obviously (or “fail fast, fail hard”, which, coincidentally, is also why I vastly prefer strongly typed languages, don’t swallow exceptions, etc)

To demonstrate, let me offer a super-simple example, which turned out to be surprisingly useful.

In C#, you can declare an enum, the default value will be whatever value represents “0”, which in most cases is the first element declared in the enum. What this means is that, in the loose case, you could have an enum as follows:

public enum SuperPower
{
  NonExistent,
  Deactivated, 
  Activated,
  Powerful,
  DemiGod
}

And by default, you might create some new Hero object (where the class represents a db entity/table) with a SuperPower property like:

[Table("Hero")]
public class Hero
{
  public int Id { get; set; }
  public SuperPower MySuperPower { get; set; }
}

So far so good.. you create a new Hero and save it to the db, and you’re safe, because the SuperPower defaulted to NonExistent. Annoying, but safe – no new heros accidentally get their powers elevated by your lazy declaration.

What if, however, you’d declared the enum like:

public enum SuperPower
{
  DemiGod,
  NonExistent,
  Deactivated, 
  Activated,
  Powerful
}

Suddenly, any new Heroes would be automatically assigned DemiGod status… and unless you expressly disempower them, chaos ensues!

You could of course, have declared the MySuperPower property with a default value, e.g.

public SuperPower MySuperPower {get; set;} = SuperPower.NonExistent;

But you’d need to remember to do that every time you ever use the enum as a property in any class or method, anywhere. Better to be explicit in the declaration of your enum and indicate the default value by assigning zero to the “best/most suitable” option:

public enum SuperPower
{
  DemiGod,
  NonExistent = 0,
  Deactivated, 
  Activated,
  Powerful
}

Mind you, if I create an new Hero using

var incredibleHulk = new Hero();

and persist them immediately to the db, when viewing the resulting db record, I couldn’t be *certain* that the (default) value of NonExistent was actually intended… I mean, Hulk is a pretty powerful superhero, so this seems strange?

What I ended up settling on, as an even more explicit option, was declare my enums more like this:

public enum SuperPower
{
  DemiGod,
  NonExistent,
  Deactivated, 
  Activated,
  Powerful,
  DEV_ERROR = 0  // Note very obvious indication that enum was NOT set explicitly
}

If we return to our hulk superhero,

var incredibleHulk = new Hero();

and persist, and then view the DB records, we’d see the DEV_ERROR value lurking in the MySuperPower column – a nice, big red flag that is sure to have catch your (and anyone viewing data’s) attention.

While this example is extremely simple, it actually saved me several times in practice (missing values from deserialized JSON, incorrect mapping logic from DTO to DB Entity, etc), and hopefully demonstrates the core ideas that I like, and feel helped us to succeed, namely:

– Favouring explicit, rather than implicit styles, and aiming for hard failure; and
– Sometimes even the simplest tricks can pay dividends.

More soon…

dale.holborow

Leave a Reply

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