Sponsors

Dynamically Emitting an Enumerated Type at Runtime

Posted on 7/3/2007

A co-worker asked me the other day if there were a way to build an enumerated type dynamically at runtime. He had an interesting problem. He wanted to be able to read a database table at startup and create an enumerated type from one of the columns in the result. Here's one way to do that. I wrote a helper method called CreateEnumType which you can adapt to your needs.

using System;
using System.Reflection;
using System.Reflection.Emit;
using System.Threading;

public class EmitAndUseEnumeratedType
{
    public static Type CreateEnumType( string enumName,
        params string[] literalNames )
    {
        // create a dynamic module to emit the new type
        AppDomain domain = Thread.GetDomain();
        AssemblyName name = new AssemblyName(
            String.Format( "EnumAssembly_{0}", enumName ) );
        AssemblyBuilder asmBuilder = domain.DefineDynamicAssembly(
            name, AssemblyBuilderAccess.Run );
        ModuleBuilder modBuilder = asmBuilder.DefineDynamicModule(
            String.Format( "EnumModule_{0}", enumName ) );

        // define the new type and populate it with literal names
        EnumBuilder enumBuilder = modBuilder.DefineEnum(
            enumName, TypeAttributes.Public, typeof( int ) );
        for (int ndx = 0; ndx < literalNames.Length; ndx++)
            enumBuilder.DefineLiteral( literalNames[ndx], ndx );

        // create the type and return it
        Type enumType = enumBuilder.CreateType();
        return enumType;
    }

    public static void Main()
    {
        // create a new enumerated type called Colors and fill it
        Type colorType = CreateEnumType( "Colors", "red", "orange",
            "yellow", "green", "blue", "indigo", "violet" );

        // create a "blue" one
        Enum blueOne = (Enum)Enum.Parse( colorType, "blue" );

        // write the enum's value to the console
        Console.WriteLine( blueOne );

        // get all of the available colors and values
        Enum[] allColors = (Enum[])Enum.GetValues( colorType );
        int[] allColorValues = (int[])Enum.GetValues( colorType );

        // enumerate the enumeration :)
        for (int ndx = 0; ndx < allColors.Length; ndx++)
        {
            Console.WriteLine( "Color '{0}' has the value {1}.",
                allColors.GetValue( ndx ), allColorValues[ndx] );
        }
    }
}

Admittedly, one of the short-comings of this code is that the enumeration that's created only contains sequential integer values starting at zero. Enumerations are not restricted in that way. An enhancement might be to pass corresponding key values from the database to the EnumBuilder's DefineLiteral method. This will create an enumerated type that's somewhat like a dictionary.

Comments

POST A COMMENT
Your name:
Your e-mail address (will not be shared with others):
Your comment: