I have windows app where-in i need to fill enum values at runtime by reading a text file named "Controls.txt". As restriction, i'm not suppose to use dictionary. Below is the default values available in the enum MyControls. I have to use enums only.
public enum MyControls
{
Button1 = 0,
Button2 = 1,
Button3 = 2,
}
If Controls.txt file is available, then content of enum should change like
public enum MyControls
{
btn1 = 0,
btn2 = 1,
btn3 = 2,
}
how do i achieve this. I also came across the link Creating / Modifying Enums at Runtime but could not get idea.
No, enums information is erased at compile time.
You can change default values of enum elements during declaration (if necessary).
No, you cannot modify types at runtime. You could emit new types, but modifying existing ones is not possible.
Enum constants are singleton and immutable objects can be used all over the application and mass and radius fields cannot be changed on the fly according to database updates. Instead, in-memory cache can be created to store mass and radius values and this internal Map can be refreshed on every database update.
I strongly think you are trying to solve the wrong problem. The value of enum is type-safety. I do not think that filling it up dynamically is a good idea. What would really be useful is to have an enum populated by a text file (for example) even before compilation. You can do this using text templates in VS.
You can find an example in my blog post here: 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
Although my example loads from a db, changing it to load from a text file should be trivial.
Apart from the fact that i agree with the other answer that says that you lose type and compile time safety, using EnumBuilderClass
should be the only way (thanks to huMpty duMpty's comment).
// 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));
}
Output:
Namespacename.MyControls.btn1 = 0
Namespacename.MyControls.btn2 = 1
Namespacename.MyControls.btn3 = 2
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With