Aries
Aries

Reputation: 301

Getting Enum from a Dynamically created Enum

Can you help me with this, in C#

Given an Enum

public enum InterferenceEnum
    {
        None = 0,
        StrongNoiseSource = 1,
        MediumNoiseSource = 2,
        VerySensitiveSignal = 4,
        SensitiveSignal = 8,
    }

and a Dynamic Enum from this

public Type GenerateEnumerations(List<string> lEnumItems, string assemblyName)
    {
        //    Create Base Assembly Objects
        AppDomain appDomain = AppDomain.CurrentDomain;
        AssemblyName asmName = new AssemblyName(assemblyName);
        AssemblyBuilder asmBuilder = appDomain.DefineDynamicAssembly(asmName, AssemblyBuilderAccess.Run);

        //    Create Module and Enumeration Builder Objects
        ModuleBuilder modBuilder = asmBuilder.DefineDynamicModule(assemblyName + "_module");
        EnumBuilder enumBuilder = modBuilder.DefineEnum(assemblyName, TypeAttributes.Public, typeof(int));
        enumBuilder.DefineLiteral("None", 0);
        int flagCnt = 1;
        foreach (string fmtObj in lEnumItems)
        {
            enumBuilder.DefineLiteral(fmtObj, flagCnt);
            flagCnt++;
        }
        var retEnumType = enumBuilder.CreateType();
        //asmBuilder.Save(asmName.Name + ".dll");
        return retEnumType;
    }

using the function above

List<string> nets_List = new List<string>() { "A", "B", "C" };
netListEnum = GenerateEnumerations(nets_List, "netsenum");

Now if i have a variable with value "None", i can get the enum by

SomeEnum enum = (SomeEnum)Enum.Parse(typeof(SomeEnum), "EnumValue");

using the first Enum, i can get the enum of string "None"

InterferenceEnum enum = (InterferenceEnum)Enum.Parse(typeof(InterferenceEnum), "None");

How can i get the enum for the dynamic generated enum?

var enum = (netListEnum.GetType())Enum.Parse(typeof(netListEnum.GetType()), "None"); 

the above code is wrong because i still "casting" it with the netListEnum Type, here is the updated code

var enum = Enum.Parse(netListEnum, "None"); 

Upvotes: 1

Views: 6552

Answers (2)

Mahdi Khalili
Mahdi Khalili

Reputation: 1198

my Enum maker:

public class XEnum
    {
        private EnumBuilder enumBuilder;
        private int index;
        private AssemblyBuilder _ab;
        private AssemblyName _name;
        public XEnum(string enumname)
        {
            AppDomain currentDomain = AppDomain.CurrentDomain;
            _name = new AssemblyName("MyAssembly");
            _ab = currentDomain.DefineDynamicAssembly(
                _name, AssemblyBuilderAccess.RunAndSave);

            ModuleBuilder mb = _ab.DefineDynamicModule("MyModule");

            enumBuilder = mb.DefineEnum(enumname, TypeAttributes.Public, typeof(int));


        }
        /// <summary>
        /// adding one string to enum
        /// </summary>
        /// <param name="s"></param>
        /// <returns></returns>
        public FieldBuilder add(string s)
        {
            FieldBuilder f = enumBuilder.DefineLiteral(s, index);
            index++;
            return f;
        }
        /// <summary>
        /// adding array to enum
        /// </summary>
        /// <param name="s"></param>
        public void addRange(string[] s)
        {
            for (int i = 0; i < s.Length; i++)
            {
                enumBuilder.DefineLiteral(s[i], i);
            }
        }
        /// <summary>
        /// getting index 0
        /// </summary>
        /// <returns></returns>
        public object getEnum()
        {
            Type finished = enumBuilder.CreateType();
            _ab.Save(_name.Name + ".dll");
            Object o1 = Enum.Parse(finished, "0");
            return o1;
        }

        public Type getType()
        {
            Type finished = enumBuilder.CreateType();
            _ab.Save(_name.Name + ".dll");
            return finished;
        }
        /// <summary>
        /// getting with index
        /// </summary>
        /// <param name="i"></param>
        /// <returns></returns>
        public object getEnum(int i)
        {
            Type finished = enumBuilder.CreateType();
            _ab.Save(_name.Name + ".dll");
            Object o1 = Enum.Parse(finished, i.ToString());
            return o1;
        }
    }

to make Enum From String Array:

 public static object STE(string[] @enum)
        {
            if (@enum.Length > 0)
            {
                XEnum xe = new XEnum("Enum");
                xe.addRange(@enum);
                return xe.getEnum();
            }
            else return null;
        }

to get a selected string from enum :

 public static object STE(string sel, string[] @enum)
        {
            XEnum xe = new XEnum("Enum");
            xe.addRange(@enum);
            var obj=  xe.getType();
            return Enum.Parse(obj, sel);
        }

to use STE's put them into static class, so to use this :

string[] ab = {"a", "b"};
object abEnum = STE(ab); //creates Enum
private object aEnum = STE("a", ab); //gets selected Value

Upvotes: 0

dbc
dbc

Reputation: 116710

You already have it -- "Enum.Parse()" returns you an enum of the specified type, boxed into an object. But the boxed object is of the enum type you created; if you call "GetType()" on it it returns that same type:

    List<string> nets_List = new List<string>() { "A", "B", "C" };
    var netListEnumType = GenerateEnumerations(nets_List, "netsenum");

    var typeName = netListEnumType.Name; // returns "netsenum" 
    var typeTypeName = netListEnumType.GetType().Name; // returns "RuntimeType", the actual name of the instantiated Type class.

    foreach (var enumName in nets_List)
    {
        var enumValBoxed = Enum.Parse(netListEnumType, enumName);
        Console.WriteLine(enumValBoxed.ToString()); // Writes "A", "B" and "C"
        Debug.Assert(enumValBoxed.GetType() == netListEnumType); // no assert yay.
    }

The only problem I see with your code is that you are doing netListEnum.GetType() but netListEnum is already of type Type -- the type you created, in fact -- so that is not necessary.

If you need to pass the enum thereby created on to some generic method in a generic object, e.g. a Dictionary<string, TEnum>, you can call it via reflection with MakeGenericMethod

Upvotes: 1

Related Questions