2
votes

What i am trying to achieve here is a bit tricky. Let me brief on a little background first before going ahead.

I am aware that we can use a enum as a type to a parameter of a method. For example I can do something like this (a very basic example)

namespace Test
{
    class DefineEnums
    {
        public enum MyEnum
        {
            value1 = 0,
            value2 = 1
        }
    }
    class UseEnums
    {
        public void UseDefinedEnums(DefineEnums.MyEnum _enum)
        { 
            //Any code here.
        }

        public void Test()
        {
            // "value1" comes here with the intellisense.
            UseDefinedEnums(DefineEnums.MyEnum.value1);
        }
    }
}

What i need to do is create a dynamic Enum and use that as type in place of DefineEnums.MyEnum mentioned above.

I tried the following. 1. Used a method which i got from the net to create a dynamic enum from a list of strings. And created a static class which i can use.

using System;
using System.Collections.Generic;
using System.Reflection;
using System.Reflection.Emit;

namespace Test
{
    public static class DynamicEnum
    {

        public static Enum finished;
        static List<string> _lst = new List<string>();

        static DynamicEnum()
        {
            _lst.Add("value1");
            _lst.Add("value2");

            finished = CreateDynamicEnum(_lst);
        }

        public static Enum CreateDynamicEnum(List<string> _list)
        {
            // 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);

            int i = 0;
            foreach (string item in _list)
            {
                eb.DefineLiteral(item, i);
                i++;
            }

            // Create the type and save the assembly.
            return (Enum)Activator.CreateInstance(eb.CreateType());
            //ab.Save(aName.Name + ".dll");


        }
    }
}
  1. Tried using the class but i am unable to find the "finished" enum defined above. i.e. I am not able to do the following
        public static void TestDynEnum(Test.DynamicEnum.finished _finished)
        {
            // Do anything here with _finished.
        }

I guess the post has become too long but i hope i have made it quite clear.

2

2 Answers

3
votes

You'll either have to pass in an object, or create your method dynamically as well.

Might I ask why you can't just use an int for this? Seems like you're going to have to dynamically create a lot of code just to be able to pass it around as an enum.

2
votes

As you create the enum dynamically, it doesn't exist until you run the code. As you can't use the type at compile time, you can't specify a parameter of that type. Creating an enum dynamically is only useful if you already have a method that expects an enum of some kind (but not any specific enum type), or if you also create the code that uses the enum dynamically.

What you can do with the enum instance is basically to get the string representation of a value, parse a string back to a value, and get a list of the defined values. This is a lot easier to accomplish with something like a Dictionary<int, string>.