Syntactic sugar (C#): Enum

August 4, 2011 by Christoff Truter C#  

Last week I had the opportunity to work with a rather expensive OCR SDK, one that could have been a great deal more elegant if the creators of the SDK used this sexy piece of syntactic chocolate, syntactic steak, syntac... uh I think you get the picture, observe the following extract.

public class OCRContext : IDisposable
	public OCRContext(int iLanguage)

There are two things I dislike about the constructor in the preceding snippet:

  1. Naming convention - iLanguage? Are you serious? This is what is called Hungarian notation, the i describes the type of the variable, in this case its trying to tell us that language is an integer.

    Personally I feel that this convention doesn't have any place in a strongly typed language like C#.

  2. Use of a magic number - we need to pass an integer to the constructor, which tells the class which language to use, but what number represents English for example? Ideally we don't want someone to dig through a thousand page manual for something so trivial.

    This "magic number" convention can lead to all kinds of confusion, observe the if condition below:

    if ((iLanguage == 17) || (iLanguage == 2))
    	// Do some funky stuff

    Not all that clear from this snippet that 17 represents polish, while 2 is supposedly french...

But wait, it gets a little bit more interesting, the developer included the following crude class:

public class Languages
	public const int Afrikaans = 33;
	public const int English = 0;

This is somewhat helpful, but it would have been nicer if we had a programmatic relation enforcing this class (telling us where we can find our languages), providing some kind of constraint at the same time.

No enumerator
Like you can see from preceding image, we still need to pass an int value, nothing is preventing or telling us to do something else.

This is where our syntactic sugar in question comes into play, we can group our constants into a neat strongly typed little box of values, which constrains us to what we can send to the parameter and leads the developer to the list of possible constants.

public class OCRContext : IDisposable
	public OCRContext(Languages language) 
	// something
	// etc..

// Poorly designed enum don't do this, read on..
public enum Languages

Obviously (like with everything else), we can misuse this piece of sugar ending up with a system suffering from hyperglycaemia.

Seeing as the underlying type of our enum is an int (can also use other integral types) it can lead to some interesting issues when using an enum as bit flags via bitwise operators.

Have a look at the following snippet (using the Languages enum in this post):

Languages languages = Languages.Afrikaans | Languages.English;

if (languages == Languages.Afrikaans)

if (languages == Languages.English)

if (languages == (Languages.Afrikaans | Languages.English))

(Note: When an enumeration is to be used in bitwise operations, be sure to set the flags attribute)

Which produces the following:

Broken Enumeration
What happened here exactly? Why did the first condition validate as true?

Well, its rather simple, if we don't provide enums with values, each member will simply be incremented starting by 0, so the value behind Languages.English is 0 - which technically means we didn't really add English to the equation.

To solve this issue you can add values to your members like seen below.

public enum Languages
	English = 1,
	Afrikaans = 2

Or according to best practices rather provide a sensible default value.

public enum Languages

There are a few other valuable design guidelines provided by Microsoft (not going to go into too much detail in this post) with regards to enumeration, which you can read more about over here.

There is one last tip I want to give you before I send you on your way.

Lets assume that you did in fact design your class like the one seen at the beginning of this post and you want to use an enum instead, but unfortunately you've got a billion people using your class already, you can simply use the obsolete attribute like seen in the following snippet.

class OCRContext
    [Obsolete("Rather use OCRContext(Languages language)")]
    public OCRContext(int iLanguage)
        // some code
    public OCRContext(Languages language)
        // some code

If the developer tries to use the old constructor, he will get the following warning in his IDE (assuming he's using Visual Studio):


Additional reading

Enumeration Design
Enumeration Types (C# Programming Guide)
When to Use an Enumeration

Leave a Comment

RE: Constructor Chaining January 26, 2012 by Christoff Truter

Unchain my constructor, baby let me be.... hehehe. Assuming of course that the old constructor supports the whole idea of flags (or not), I guess its upto the scenario. But yes, I definitely agree.

Feedback January 25, 2012 by Mick

I agree, there's not much that's more frustrating when people writing APIs don't use enums. Though it's not the point of the article, in the spirit of writing maintainable code the second constructor probably shouldn't have a body and should be: public OCRContext(Languages language) : this((int)language) instead.

    Latest Posts

    Paris Terror Attacks

    November 14, 2015

    Personal Movie Database Part 1 - Overview (JQuery Mobile AngularJS)

    November 10, 2015

    JavaScript Tip - Checking for undefined

    April 9, 2015

    Simple JavaScript Shop - Back to the future : Part 1

    March 20, 2015

    Getting my hands dirty with TypeScript

    February 17, 2015

    Quick and dirty look at TypeScript

    January 29, 2015

    My personal life in review

    January 21, 2015

    Quick rundown of possible new C# 6.0 features (perhaps, maybe - I think)

    January 19, 2015

    Proof of Concept - JavaScript Mediator Framework

    January 13, 2015

    JavaScript Tip - Benchmarking

    January 7, 2015

    Most Commented on Posts

    Moving items between listboxes in example

    Move items between two listboxes in, VB.NET) and PHP
    June 12, 2008

    Simple WYSIWYG Editor

    Creating a WYSIWYG textbox for your website is actually quite simple.
    February 1, 2007

    C# YouTube : Google API

    Post on how to integrate with YouTube using the Google Data API
    March 12, 2011

    Populate a TreeView Control C#

    Populate a TreeView control in a windows application.
    August 27, 2009

    Cross Browser Issues: Firefox Word Wrapping

    Firefox word wrapping issues
    June 9, 2008

    Angular   ASP.NET   Astronomy   Breaking News   C#   C++   Coding Horrors   Comedy   Cross Browser   Design Patterns   Google API   IIS   Integration   JavaScript   Jquery Mobile   Love and War   Microsoft Office   Personal   PHP   South Africa   SQL   Threading   TypeScript   Visual Basic   XML