36

I have an enum of the following structure:

public enum DType
{       
    LMS =  0,
    DNP = -9,
    TSP = -2,
    ONM =  5,
    DLS =  9,
    NDS =  1
}

I'm using this enum to get the names and the values. Since there is a requirement to add more types, I need to read the type and the values from an XML file. Is there any way by which I can create this enum dynamically from XML file so that I can retain the program structure.

Rajan Mishra
  • 1,178
  • 2
  • 14
  • 30
Milen
  • 5,553
  • 5
  • 21
  • 12

2 Answers2

51

Probably, you should consider using a Dictionary<string, int> instead.

If you want to generate the enum at compile-time dynamically, you might want to consider T4.

Mehrdad Afshari
  • 414,610
  • 91
  • 852
  • 789
  • 1
    I agree. All references to the individual values of an enum are converted to numeric literals at compile time. This can create potential versioning issues. It is however not impossible. Somewhere I read CodeDom can help you but be aware it is lot of work. Not sure if its worht the effort. – Prithis May 13 '09 at 11:44
  • +1 for [T4](http://www.hanselman.com/blog/T4TextTemplateTransformationToolkitCodeGenerationBestKeptVisualStudioSecret.aspx) – elimad Oct 07 '14 at 03:39
40

Use EnumBuilder to create enums dynamically. This would require usage of Reflection.

STEP 1 : CREATING ENUM USING ASSEMBLY/ENUM BUILDER

// Get the current application domain for the current thread.
AppDomain currentDomain = AppDomain.CurrentDomain;

// Create a dynamic assembly in the current application domain,
// and allow it to be executed and saved to disk.
AssemblyName aName = new AssemblyName("TempAssembly");
AssemblyBuilder ab = currentDomain.DefineDynamicAssembly(aName, AssemblyBuilderAccess.RunAndSave);

// Define a dynamic module in "TempAssembly" assembly. For a single-
// module assembly, the module has the same name as the assembly.
ModuleBuilder mb = ab.DefineDynamicModule(aName.Name, aName.Name + ".dll");

// Define a public enumeration with the name "Elevation" and an 
// underlying type of Integer.
EnumBuilder eb = mb.DefineEnum("Elevation", TypeAttributes.Public, typeof(int));

// Define two members, "High" and "Low".
eb.DefineLiteral("Low", 0);
eb.DefineLiteral("High", 1);

// Create the type and save the assembly.
Type finished = eb.CreateType();
ab.Save(aName.Name + ".dll");

STEP 2: USING THE CREATED ENUM

System.Reflection.Assembly ass = System.Reflection.Assembly.LoadFrom("TempAssembly.dll");
System.Type enumTest = ass.GetType("Elevation");
string[] values = enumTest .GetEnumNames();

Hope that helps

Rajaram L
  • 401
  • 4
  • 2
  • Amazing!!! i didn't know you could create an assembly at runtime – Luis Pena Oct 07 '15 at 17:35
  • Yes , but how can I promise that this enum will exist in order to build my application successfully? – kuskmen Sep 17 '16 at 08:12
  • 1
    I know this is a bit late, but since this duplicated another post, I'll answer kuskmen's question: you don't. You're generating the types at _runtime_. – ProgrammingLlama Apr 19 '17 at 10:34
  • 1
    Upvoted because I found this example of creating assemblies at runtime that you can populate with runtime specific types, code, etc. stunning. The code is clear and the concept powerful. Not sure when I might use something like this, but I blown away by the elegant flexibility of this approach. – RB Davidson Aug 17 '17 at 13:05
  • Would this effectively leak memory if used repeatedly? – SomeInternetGuy Sep 13 '18 at 01:14
  • Simple and working solution. **But @Mehrdad Afshari Solution may be better** for most cases if possible `Dictionary` may be easier and better to work with, also for others to later maintain. from my point of view. – LamaTo Jan 22 '19 at 13:51