Tigraine

Daniel Hoelbling-Inzko talks about programming

A better way to write enumerations

Posted by Daniel Hölbling on August 2, 2009

One thing I constantly struggle with is enumerations. They are inherently dumb, carry little more than one integer of actual information and usually mean a lot more than their name conveys.

Let aside Enumerations as method option flags (where they actually do make sense!), the usual line of business application will have these three enumerations somewhere:

image

Now, let’s ignore all the others our most basic example would be the Sex enumeration that has usually one but only one use: How to salute your user when communicating.

Like the obvious emails you get:

Hello Mr. Hölbling, we’d like to thank you for your …

You get the drift. If I’d perform a sex change someday the system should address me as Mrs. Hölbling (and actually, that type of thing is much more of a problem in German than in English, but anyway).
And the code to do that would look something like this:

string salutation = "Mr.";
if (sex == Sex.Female) salutation = "Mrs.";

Console.WriteLine("Dear {0} Hölbling", salutation);

In a typical web application you’ll be repeating this piece of code numerous times, since being polite doesn’t hurt. Where this would actually hurt is if you’d mindlessly copy&paste that piece of code wherever you have to greet your user. You’d be violating DRY and the guy maintaining your code in 2 or 3 years will find out where you live and kill you in your sleep some day.

What I’d like to see as a solution to this is to simply have a method living on that enumeration. Like:

Console.WriteLine("Dear {0} Hölbling", sex.GetSalutation());

And that’s possible, just not very convenient. You’ll have to emulate the enumeration through a class:

public class Sex
{
    public int Id { get; private set; }
    public string Salutation { get; private set; }
}

Should work like a charm, but you loose the benefit of typing Sex.Female when setting a gender. So here is how to make a class look & feel like a enum without the limitations:

public class Sex
{
    public static Sex Male = new Sex{Id = 0, Salutation = "Mr."};
    public static Sex Female = new Sex{Id = 1, Salutation = "Mrs."};

    public int Id { get; private set; }     public string Salutation { get; private set; } }

You can now do stuff like:

new User()
    {
        Name = "Daniel",
        Sex = Sex.Male
    };

And if you have added equality on the id (as you always should) you could make decisions like with real enumerations:

if (user.Sex == Sex.Female)
{
    //Do Something
}

Now you could even go ahead and subclass your Sex class and dump logic in there if you please. Hell, even persist that type to a database using NH and the WellKnownInstanceType as Fabio points out.

The full implementation of our above Sex enumeration is beyond the jump.

public class Sex
{
    public static Sex Male = new Sex {Id = 0, Salutation = "Mr."};
    public static Sex Female = new Sex {Id = 1, Salutation = "Mrs."};

    public int Id { get; private set; }     public string Salutation { get; private set; }

    #region Equality methods

    public bool Equals(Sex other)     {         if (ReferenceEquals(null, other)) return false;         if (ReferenceEquals(this, other)) return true;         return other.Id == Id;     }

    public override bool Equals(object obj)     {         if (ReferenceEquals(null, obj)) return false;         if (ReferenceEquals(this, obj)) return true;         if (obj.GetType() != typeof (Sex)) return false;         return Equals((Sex) obj);     }

    public override int GetHashCode()     {         return Id;     }

    #endregion }

Filed under net, programmierung
comments powered by Disqus

My Photography business

Projects

dynamic css for .NET

Archives

more