2

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.

Bill the Lizard
  • 398,270
  • 210
  • 566
  • 880
samar
  • 5,021
  • 9
  • 47
  • 71

2 Answers2

3

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.

Lasse V. Karlsen
  • 380,855
  • 102
  • 628
  • 825
  • I cannot use int here because i need the values ("value1" and "value2" in my case) in the intellisense which i cannot get if i use int. Also value1 and value2 is generated dynamically and cannot be hardcoded in a static enum. I have modified my post to incorporate the same. – samar May 21 '10 at 08:41
  • You won't get that in intellisense when you're generating the code dynamically at runtime. If you're pregenerating an assembly, adding a reference to that, then your method using the enum as a parameter type should work just fine. – Lasse V. Karlsen May 21 '10 at 09:46
  • Hi Lasse I know that staying in the same assembly would not work so I had seperated the creation of enum part into a different assembly and using the same in a seperate assembly. Still was not able to find the enum. – samar May 21 '10 at 11:29
  • Are you generating the enums, saving the assembly, and creating a reference to the assembly? Or are you creating the enums only at runtime? – Lasse V. Karlsen May 21 '10 at 11:32
  • Hi Lasse sorry to have replied to this thread so late. As you had recommended I was able to accomplish this by seperating the code to generate the dynamic enum to a seperate dll and then giving the reference of the dll to the main assembly. Thanks for your response. You can move your comments as answer so that others can benefit from the same. – samar Dec 21 '10 at 10:22
2

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>.

Guffa
  • 687,336
  • 108
  • 737
  • 1,005
  • Hi Guffa i am getting what you are trying to say here. I will create a dictionary which will contain the values which i want to show when any developer tries to use my method. Just 1 question here. How can i use this dictionary in parameters when i am creating a method? Please advice. – samar May 21 '10 at 09:14