Click here to Skip to main content
13,801,049 members
Click here to Skip to main content
Add your own
alternative version


50 bookmarked
Posted 3 Mar 2006

Descriptive Enumerations

, 8 Mar 2006
Rate this:
Please Sign up or sign in to vote.
Using .NET 2.0 generics to allow for enum like classes with human readable descriptions.


Those of us who write ASP.NET for living often come across the problem of wanting to use enums in our pages. For example, you may have a page that allows someone to register for an airplane seat. Then, you may have some code that looks like:

public enum SeatType

public class Registration
    SeatType wantsSeat;

Back in your ASP.NET page, you may loop over all the enum values, using something like:

foreach (string s in Enum.GetNames(typeof(SeatType)))
    string name = s;
    SeatType t = (SeatType) Enum.Parse(typeof(SeatType),s);
    int val = (int) t;

    //do something with name and val like
    //add them to an <option> tag

This code is a bit ugly, but it's worth keeping due to the fact that we can have methods like:

public SeatType GetPassengerSeatType(Passenger p) {
    return p.Seat;

The real issue arises when we add a new seat type to our enum that isn't a valid identifier. Note that Enum.GetNames simply returns the names of the enumerated constants. C# doesn't allow us to have something like:

public enum SeatType
    Anything Except Seat Near Bathroom

Since "Anything Except Seat Near Bathroom" isn't a valid identifier, I've seen several people make use of attributes to do something like this:

public enum SeatType
    [Description("Window")] Window=1,
    [Description("Aisle")] Aisle=2,
    [Description("Anything Except Seat" +
        " Near Bathroom")] AnythingExceptSeatNearBathroom

public static string GetEnumDescription(Enum value)
    FieldInfo fi= value.GetType().GetField(value.ToString());
    DescriptionAttribute[] attributes =
      typeof(DescriptionAttribute), false);
    return (attributes.Length>0) ?
            attributes[0].Description :

This code works, but it's not really good object oriented design: we're asking another class to retrieve information about our enum type. Clearly, what we would like to do is have a Description as a property of each member of our enum, rather than as an attribute of each member.

With .NET 2.0 and generics, we are able to have a very clean solution to the problem.

Using the code

I created a simple generic abstract class called DescriptiveEnum that will allow you to have...descriptive enums!

Before explaining how the DescriptiveEnum class works that makes this possible, I'll show you how to use it to solve the example we mentioned above. Here is the new SeatType "enum".

public class SeatType : DescriptiveEnum<SeatType,int>
    public static readonly SeatType Window = 
           new SeatType("Window Seat",1);
    public static readonly SeatType Aisle = 
           new SeatType("Aisle Seat", 2);
    public static readonly SeatType 
           AnythingExceptSeatNearBathroom = 
           new SeatType("Anything Except Seat Near Bathroom", 3);

    private SeatType(string desc, int code) : base(desc,code)

Only three things are necessary here:

  1. You need to inherit from DescriptiveEnum and pass the name of your inheriting class as the first generic type. The second generic type can be any value type that you want to use to store your enum values. By default, real .NET enums use integers to store constant enum values. So, I am doing the same thing in the example above. But again, you can store doubles, etc.
  2. Define a private constructor for your type that takes a string and the same type that you specified for the generic enum value. Since I specified int, I need to specify int in the constructor. You can't actually get this wrong; if you try to have a constructor that takes a double when you specified an int in your generic type, the compiler will throw an error at you. The important point to realize here is that the constructor should be private. Other classes should not be creating new instances of your enum type.
  3. Define public static readonly types of your class, and instantiate them by calling your private constructor, passing in a unique code for each enum. In the example above, I specified 1,2,3. You can make these anything you want as long as they are unique. If they are not unique, the class will throw an exception at run time.

So after doing the above, we have a data type that looks and feels just like a built-in enum, but with our descriptions:

SeatType c = SeatType.Aisle;
string desc = SeatType.AnythingExceptSeatNearBathroom.Description;

Additionally, our base class defines some other useful methods:

SeatType c;
int seatkind = GetSeatTypeFromDatabaseSomeWhere();

c = SeatType.GetEnumFromCode(seatkind);

SeatType[] allSeatTypes = SeatType.GetEnumMembers();

Finally, with generics, the base class is able to define public static explicit operator conversions to and from the enum constant you define (int, in our example above). So, this lets you use casting exactly like you do with enums. So you don't even have to call:


like we did above. You can actually just do:

SeatType c = (SeatType) GetSeatTypeFromDatabaseSomeWhere();

Likewise, you can call:

int x = (int) SeatType.Aisle

if you want. Although, generally, I would call the SeatType.Aisle.Code member.

And that's all there is to it. Generics is a beautiful thing.


  • 1.0 - original release.


This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


About the Author

Tim Clark
Web Developer
United States United States
Tim Clark graduated in 2005 with an MS in Computer Science. He is currently employed as a .NET developer.

You may also be interested in...

Comments and Discussions

GeneralMy vote of 4 Pin
S.P.Tiwari7-Dec-11 19:13
professionalS.P.Tiwari7-Dec-11 19:13 
GeneralBuild warning Pin
golan.barnov10-Sep-07 4:23
membergolan.barnov10-Sep-07 4:23 
Generalswitch Pin
DynV15-Jun-07 5:53
memberDynV15-Jun-07 5:53 
Questionstring Data Type for CodeType Pin
Jason Law16-Apr-07 18:55
memberJason Law16-Apr-07 18:55 
AnswerRe: string Data Type for CodeType Pin
Tim Clark17-Apr-07 4:56
memberTim Clark17-Apr-07 4:56 
QuestionWorks Great But .... What About Switch Statements? Pin
S432**%$13-Oct-06 13:31
memberS432**%$13-Oct-06 13:31 
AnswerRe: Works Great But .... What About Switch Statements? Pin
Tim Clark16-Oct-06 6:37
memberTim Clark16-Oct-06 6:37 
QuestionWhere is DescriptiveEnumInvalidCodeException Pin
okcode24-Jul-06 0:19
memberokcode24-Jul-06 0:19 
GeneralXmlSerializable Pin
ryanmunson10-May-06 12:59
memberryanmunson10-May-06 12:59 
GeneralRe: XmlSerializable Pin
Tim Clark11-May-06 5:51
memberTim Clark11-May-06 5:51 
GeneralRe: XmlSerializable Pin
ryanmunson11-May-06 16:54
memberryanmunson11-May-06 16:54 
GeneralRe: XmlSerializable Pin
Tim Clark11-May-06 18:01
memberTim Clark11-May-06 18:01 
GeneralRe: XmlSerializable Pin
ryanmunson11-May-06 18:58
memberryanmunson11-May-06 18:58 
Generalswitch Pin
roman.wagner29-Mar-06 7:15
memberroman.wagner29-Mar-06 7:15 
GeneralRe: switch Pin
Tim Clark30-Mar-06 10:36
memberTim Clark30-Mar-06 10:36 
QuestionVery Nice indeed, but...increments? Pin
Tim Speekenbrink24-Mar-06 6:03
memberTim Speekenbrink24-Mar-06 6:03 
AnswerRe: Very Nice indeed, but...increments? Pin
Tim Clark24-Mar-06 6:22
memberTim Clark24-Mar-06 6:22 
GeneralRe: Very Nice indeed, but...increments? Pin
Tim Speekenbrink24-Mar-06 6:33
memberTim Speekenbrink24-Mar-06 6:33 
QuestionNice, but what about [Flags] Pin
Memeoid15-Mar-06 8:54
memberMemeoid15-Mar-06 8:54 
AnswerRe: Nice, but what about [Flags] Pin
Tim Clark16-Mar-06 20:55
memberTim Clark16-Mar-06 20:55 
JokeWonderfull Pin
Mohammad Mir mostafa15-Mar-06 3:39
memberMohammad Mir mostafa15-Mar-06 3:39 
GeneralSmooth Pin
lofty_29-Mar-06 15:09
memberlofty_29-Mar-06 15:09 
GeneralAwesome Pin
Steve Hansen8-Mar-06 22:47
memberSteve Hansen8-Mar-06 22:47 
GeneralVery Nice! Pin
K.Collins8-Mar-06 4:58
memberK.Collins8-Mar-06 4:58 
Generalnice solution Pin
Ajek6-Mar-06 21:47
memberAjek6-Mar-06 21:47 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Cookies | Terms of Use | Mobile
Web03 | 2.8.181215.1 | Last Updated 8 Mar 2006
Article Copyright 2006 by Tim Clark
Everything else Copyright © CodeProject, 1999-2018
Layout: fixed | fluid