
Creating Enum instances using Reflection
Started by Saturnim, May 29 2011 11:33 AM
12 replies to this topic
#1
Posted 29 May 2011 - 11:33 AM
Hi!
Is it possible to create an instance of enum by using reflection ? I can't to get access to constructor of my Enum and I can't create it. I tried TypeOfMyEnum.GetConstructor( new Type[]{}), TypeOfMyEnum.GetConstructor( new Type[]{typeof(Int32)}) , TypeOfMyEnum.GetMethod(".ctor")... and result is null
#2
Posted 30 May 2011 - 12:07 AM
What exactly are you trying to do? Enums are basically just strongly typed integers, so if you know the value of the enum a simple cast will do, there's no need to call constructors.
#3
Posted 30 May 2011 - 06:51 AM
I agree: Enums are useful at compile time. Where is the sense of building them at runtime?
Maybe you are looking for something like the Factory pattern.
Cheers
Maybe you are looking for something like the Factory pattern.
Cheers
Biggest fault of Netduino? It runs by electricity.
#4
Posted 30 May 2011 - 08:21 AM
I am trying to transport objects between full.Net and MF (Xml serialization). And I want to recreate object with has field enumertor. Other fields have constructor or are ValueTypes which I can create by Convert class from String ( I have all in xml) . Array can create by CreateInstance method.... but enum ?
#5
Posted 30 May 2011 - 11:46 AM
Hmmm...
To create an instance of a class, you must have its type declaration. You cannot create an instance of a type without any declaration at all (unless you're doing something with IL-emits).
So, if you have the type MyEnum on the source platform, you must have the same type MyEnum on the target also. At this point the problem is over.
It could be something like this:
To test it:
Cheers
To create an instance of a class, you must have its type declaration. You cannot create an instance of a type without any declaration at all (unless you're doing something with IL-emits).
So, if you have the type MyEnum on the source platform, you must have the same type MyEnum on the target also. At this point the problem is over.
It could be something like this:
public static object Parse(Type type, string text) { FieldInfo[] fields = type.GetFields(BindingFlags.Static | BindingFlags.Public); for (int i = 0, count = fields.Length; i < count; i++) { FieldInfo fi = fields[i]; if (fi.Name == text) { return fi.GetValue(null); } } throw new ArgumentException("Cannot parse the specified string"); }
To test it:
public enum MyEnum { Uno, Due, Tre, } MyEnum test = (MyEnum)Parse(typeof(MyEnum), "Due");
Cheers
- Mati likes this
Biggest fault of Netduino? It runs by electricity.
#6
Posted 30 May 2011 - 04:49 PM
Just FYI: to save space, enum names are partially/completed compiled out of .NET MF code. So I'm not sure that there's going to be a lot of support for enum reflection built into .NET MF.
Chris
#7
Posted 30 May 2011 - 07:23 PM
Thank you for yours replies. Mario Vernari, did you build this example ? I don't think because GetFileds returns empty array of FieldsInfo and this example throws exception. I dont understand this ... in Disassembly is showing clearly, that static fileds are existing in this enum type:
TypeDef #4 (02000005) ------------------------------------------------------- TypDefName: MyEnum (02000005) Flags : [NestedPublic] [AutoLayout] [Class] [Sealed] [AnsiClass] (00000102) Extends : 01000002 [TypeRef] System.Enum EnclosingClass : MFConsoleApplication1.Program (02000004) Field #1 (04000004) ------------------------------------------------------- Field Name: value__ (04000004) Flags : [Public] [SpecialName] [RTSpecialName] (00000606) CallCnvntn: [FIELD] Field type: I4 Field #2 (04000005) ------------------------------------------------------- Field Name: one (04000005) Flags : [Public] [Static] [Literal] [HasDefault] (00008056) DefltValue: (I4) 0 CallCnvntn: [FIELD] Field type: ValueClass MyEnum Field #3 (04000006) ------------------------------------------------------- Field Name: two (04000006) Flags : [Public] [Static] [Literal] [HasDefault] (00008056) DefltValue: (I4) 1 CallCnvntn: [FIELD] Field type: ValueClass MyEnum Field #4 (04000007) ------------------------------------------------------- Field Name: three (04000007) Flags : [Public] [Static] [Literal] [HasDefault] (00008056) DefltValue: (I4) 2 CallCnvntn: [FIELD] Field type: ValueClass MyEnumEnum Declaration:
public enum MyEnum { one, two, three }Trying of getting fields:
Type TypeOfMyEnum = typeof(MyEnum); FieldInfo[] enumFileds = TypeOfMyEnum.GetFields(BindingFlags.Static | BindingFlags.Public );Maybe I should use other BindingFlags? If I use NonPublic I have access to value__ but no to static fileds...
#8
Posted 02 December 2011 - 10:37 PM
Hi Mario.
i get an Exception "Cannot parse the specified string" when i try to use your code...
is this for 4.1 or a higher version?
thanks.
#9
Posted 28 February 2012 - 05:28 PM
What namespace is the Parse command under for (MyEnum)Parse(typeof(MyEnum), "Due");
There is an Enum.Parse under the full framework but it does not exist under MF.
Trying to figure out how to parse an enum myself.
There is an Enum.Parse under the full framework but it does not exist under MF.
Trying to figure out how to parse an enum myself.
#10
Posted 28 February 2012 - 07:25 PM
Hmmm...You guys are right.
The snippet above was tested on the regular framework, but it seems that on the MF is not working.
By disassembling the code, the enum's constants are correctly translated to "fields".
The regular framework yields the enum's components as GetFields() applied on the type itself, as the snippet shows.
In the MF, seems that there's no way to retrieve the fields from an enumeration. The GetFields() method returns always zero cells.
Well, it sounds much like a bug than a limitation. However, this is another good reason to prefer constant or standard classes over the Enum.
My apologies for the mismatch.
Cheers
The snippet above was tested on the regular framework, but it seems that on the MF is not working.
By disassembling the code, the enum's constants are correctly translated to "fields".
.field public static literal valuetype Sure32x16.MyEnum Tre = int32(0x00000002)
The regular framework yields the enum's components as GetFields() applied on the type itself, as the snippet shows.
In the MF, seems that there's no way to retrieve the fields from an enumeration. The GetFields() method returns always zero cells.
Well, it sounds much like a bug than a limitation. However, this is another good reason to prefer constant or standard classes over the Enum.
My apologies for the mismatch.
Cheers
Biggest fault of Netduino? It runs by electricity.
#11
Posted 28 February 2012 - 09:33 PM
I guess case statements have their place

#12
Posted 29 February 2012 - 06:31 AM
The following is nearly the same as an Enum, and it works well:
I'd add that is also expandable using the "partial" modifier.
Cheers
public static class MyEnum { public static readonly int Uno = 1; public static readonly int Due = 2; public static readonly int Tre = 3; } public class Program { public static void Main() { //MyEnum test = (MyEnum)Parse(typeof(MyEnum), "Due"); int test = (int)Parse(typeof(MyEnum), "Due"); // ... } public static object Parse(Type type, string text) { FieldInfo[] fields = type.GetFields(BindingFlags.Static | BindingFlags.Public); for (int i = 0, count = fields.Length; i < count; i++) { FieldInfo fi = fields[i]; if (fi.Name == text) { return fi.GetValue(null); } } throw new ArgumentException("Cannot parse the specified string"); } }
I'd add that is also expandable using the "partial" modifier.
Cheers
- Bendage likes this
Biggest fault of Netduino? It runs by electricity.
#13
Posted 29 February 2012 - 05:14 PM
Very nice!
Thank you!
0 user(s) are reading this topic
0 members, 0 guests, 0 anonymous users