Netduino home hardware projects downloads community

Jump to content


The Netduino forums have been replaced by new forums at community.wildernesslabs.co. This site has been preserved for archival purposes only and the ability to make new accounts or posts has been turned off.
Photo

Creating Enum instances using Reflection


  • Please log in to reply
12 replies to this topic

#1 Saturnim

Saturnim

    Member

  • Members
  • PipPip
  • 12 posts

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 Fabian Nunez

Fabian Nunez

    Member

  • Members
  • PipPip
  • 10 posts

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 Mario Vernari

Mario Vernari

    Advanced Member

  • Members
  • PipPipPip
  • 1768 posts
  • LocationVenezia, Italia

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
Biggest fault of Netduino? It runs by electricity.

#4 Saturnim

Saturnim

    Member

  • Members
  • PipPip
  • 12 posts

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 Mario Vernari

Mario Vernari

    Advanced Member

  • Members
  • PipPipPip
  • 1768 posts
  • LocationVenezia, Italia

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:

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
Biggest fault of Netduino? It runs by electricity.

#6 Chris Walker

Chris Walker

    Secret Labs Staff

  • Moderators
  • 7767 posts
  • LocationNew York, NY

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 Saturnim

Saturnim

    Member

  • Members
  • PipPip
  • 12 posts

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 MyEnum

Enum 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 Jay75

Jay75

    New Member

  • Members
  • Pip
  • 7 posts

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 Bendage

Bendage

    Advanced Member

  • Members
  • PipPipPip
  • 153 posts
  • LocationIrvine, CA

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.

#10 Mario Vernari

Mario Vernari

    Advanced Member

  • Members
  • PipPipPip
  • 1768 posts
  • LocationVenezia, Italia

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



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

Bendage

    Advanced Member

  • Members
  • PipPipPip
  • 153 posts
  • LocationIrvine, CA

Posted 28 February 2012 - 09:33 PM

I guess case statements have their place :P

#12 Mario Vernari

Mario Vernari

    Advanced Member

  • Members
  • PipPipPip
  • 1768 posts
  • LocationVenezia, Italia

Posted 29 February 2012 - 06:31 AM

The following is nearly the same as an Enum, and it works well:



    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
Biggest fault of Netduino? It runs by electricity.

#13 Bendage

Bendage

    Advanced Member

  • Members
  • PipPipPip
  • 153 posts
  • LocationIrvine, CA

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

home    hardware    projects    downloads    community    where to buy    contact Copyright © 2016 Wilderness Labs Inc.  |  Legal   |   CC BY-SA
This webpage is licensed under a Creative Commons Attribution-ShareAlike License.