从动态创建的Enum中获取Enum

本文关键字:Enum 获取 动态 创建 | 更新日期: 2023-09-27 18:16:56

你能用c#帮我吗?

给定一个Enum

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

和来自

的动态Enum
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;
    }

使用上面的函数

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

现在,如果我有一个值为"None"的变量,我可以通过

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

使用第一个Enum,我可以得到字符串"None"的Enum

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

如何获得动态生成的枚举的枚举?

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

上面的代码是错误的,因为我仍然用netListEnum类型"铸造"它,这里是更新的代码

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

从动态创建的Enum中获取Enum

您已经有了它——"Enum.Parse()"返回指定类型的枚举,并装箱成一个对象。但是盒装对象是你创建的枚举类型;如果你对它调用"GetType()"它会返回相同的类型:

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

我在你的代码中看到的唯一问题是你正在做netListEnum.GetType(),但netListEnum已经是Type类型-实际上是你创建的类型-所以这是不必要的。

如果您需要将枚举传递给泛型对象中的泛型方法,例如Dictionary<string, TEnum>,您可以通过MakeGenericMethod

的反射来调用它。

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;
        }
    }

创建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;
        }

从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);
        }

使用STE将它们放入静态类中,所以要使用这个:

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