[c#] Extending Enums on .NET

One of these days I had the need to create and extensible enum. Extensible in a way that allows people to add items to it, but outside the assembly where the enum is declared.

The short answer to this is that enums are not extensible Triste

It become clear that I would need to find a workaround. Since we had some legacy code already working, it was necessary to keep the normal usage of the enum (i.e. switch – case).

The following solution may not be the best one, but it’s working good, allowing the extension of the enum and still preserve their traditional usage on the switch-case blocks.

Note: the following code is used to “replace” enums deriving from INT. Deriving from other datatype involves changing the operators.


The idea is simple: having a class with some int constants, replacing the enum values. Lets say we have an enum called CustomerType:


public enum CustomerType
{
   National = 1,
   International = 2
}

Using the new approach, we’ll have a class replacing the enum, using static constants as the items, and implementing two operators (from int and to int):


public class CustomerType
{
   public int Value { get; set; }

  public const int National = 1;
  public const int International = 2;

  public CustomerType (int value)
  {
    Value = value;
  }

  public static implicit operator int(CustomerType cType)
  {
    return cType.Value;
  }

  public static implicit operator CustomerType (int value)
  {
    return new CustomerType (value);
  }
}

The extension class then would just have to implement the base class and override the constructor:

public class CustomerTypeExtension : CustomerType
{
      public const int Premium= 3;
      public CustomerTypeExtension (int value)   : base(value)
      {   }
}

The usage for this is now as using a normal enum:

CustomerType cType= CustomerTypeExtension.PremiumCustomer;

switch (cType)
{
    case CustomerTypeExtension .National:
            Console.WriteLine("National");
            break;
    case CustomerTypeExtension .Interational:
            Console.WriteLine("International");
            break;
    case CustomerTypeExtension .Premium:
            Console.WriteLine("Premium");
            break;
}

Note: if you need to serialize it, it’s necessary to add and empty constructor to the base class.

Cheers Piscar de olho

Leave a Reply

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

CAPTCHA Image

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>