2014-12-04 72 views
8

我有Windows应用程序在哪里 - 我需要在运行时通过读取名为“Controls.txt”的文本文件来填充枚举值。 作为限制,我不假设使用字典。以下是枚举MyControls中的默认值。 我必须使用枚举只有在C#运行时填充/更新枚举值

public enum MyControls 
{ 
    Button1 = 0, 
    Button2 = 1, 
    Button3 = 2, 
} 

如果Controls.txt文件可用,则枚举的内容应该改变像

public enum MyControls 
{ 
    btn1 = 0, 
    btn2 = 1, 
    btn3 = 2, 
} 

我如何实现这一目标。我也遇到了链接Creating/Modifying Enums at Runtime,但不知道。

+5

有你看着[EnumBuilder类](http://msdn.microsoft.com/en-us/library/system.reflection.emit.enumbuilder%28v= vs.110%29.aspx)?你也许需要看看[C#中的动态枚举](http://stackoverflow.com/questions/725043/dynamic-enum-in-c-sharp) – 2014-12-04 09:11:50

+0

为什么首先使用'enum'? – Rik 2014-12-04 09:14:12

+0

这里有什么要求?它是否被用于自动将Enum绑定到组合框或类似的框架? – 2014-12-04 09:17:20

回答

4

我强烈地认为你试图解决错误的问题。枚举的值是类型安全的。我不认为动态填充它是一个好主意。真正有用的是在文本文件(例如)编译之前填入一个枚举。你可以使用VS中的文本模板来做到这一点。从DB http://skleanthous.azurewebsites.net/post/2014/05/21/Creating-enums-from-the-database-and-using-them-in-Entity-framework-5-and-later-in-model-first

虽然我的例子负荷,改变它从一个文本文件中加载应该是微不足道的:

你可以在我的博客帖子在这里找到一个例子。

3

除了这个事实,我同意其他答案,说你失去了类型和编译时间的安全性,使用EnumBuilderClass应该是唯一的方法(感谢huMpty duMpty的评论)。

// sample "file": 
string fileContent = @" 
btn1 = 0, 
btn2 = 1, 
btn3 = 2, 
"; 
var enumBody = fileContent.Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries) 
    .Select(line => new { bothToken = line.Trim().Trim(',').Split('=') }) 
    .Where(x => x.bothToken.Length == 2) 
    .Select(x => new { Name = x.bothToken[0].Trim(), Value = int.Parse(x.bothToken[1].Trim()) }); 

AppDomain currentDomain = AppDomain.CurrentDomain; 
AssemblyName asmName = new AssemblyName("EnumAssembly"); 
AssemblyBuilder asmBuilder = currentDomain.DefineDynamicAssembly(asmName, AssemblyBuilderAccess.RunAndSave); 
ModuleBuilder mb = asmBuilder.DefineDynamicModule(asmName.Name, asmName.Name + ".dll"); 
string enumTypeName = string.Format("{0}.{1}", typeof(MyControls).Namespace, typeof(MyControls).Name); 
EnumBuilder eb = mb.DefineEnum(enumTypeName, TypeAttributes.Public, typeof(int)); 
foreach(var element in enumBody) 
{ 
    FieldBuilder fb1 = eb.DefineLiteral(element.Name, element.Value); 
} 
Type eType = eb.CreateType(); 

foreach (object obj in Enum.GetValues(eType)) 
{ 
    Console.WriteLine("{0}.{1} = {2}", eType, obj, ((int)obj)); 
} 

输出:

Namespacename.MyControls.btn1 = 0 
Namespacename.MyControls.btn2 = 1 
Namespacename.MyControls.btn3 = 2 
+0

让我试试它,并更新你的结果。 – sia 2014-12-04 09:42:10