views:

1221

answers:

4

My C# class MyClass (below) has members a, b, c, d, e, and f.

I'd like to use reflection to obtain a list of the data types of those members; for example (borrowing from Python notation): [ char[], ushort, char, byte, uint, ulong ].

class MyClass
{
    public  char [ ]    a ;
    public  ushort      b ;
    public  char        c ;
    public  byte        d ;
    public  uint        e ;
    public  ulong       f ;
}

class MainClass
{
public static void Main ( string [] args )
    {
        // get an array (or some kind of list) of MyClass' fields' data types ...
        // for example:  { char[], ushort, char, byte, uint, ulong }

        // I've tried the following, but can't get a column of just the data types, alone ...
        MemberInfo[] theMemberInfoArray = typeof(MyClass).GetMembers() ;
        foreach (MemberInfo mi in theMemberInfoArray)
            if (mi.MemberType == MemberTypes.Field)
                    Console.WriteLine ( "<" + mi.MemberType + ">\t"
                    + "<" + mi.GetType() + ">\t"
                    + "<" + mi.Name + ">\t" + mi ) ;
    }

}

Program output appears as below:

<Field> <System.Reflection.RtFieldInfo> <a>     Char[]  a
<Field> <System.Reflection.RtFieldInfo> <b>     UInt16  b
<Field> <System.Reflection.RtFieldInfo> <c>     Char    c
<Field> <System.Reflection.RtFieldInfo> <d>     Byte    d
<Field> <System.Reflection.RtFieldInfo> <e>     UInt32  e
<Field> <System.Reflection.RtFieldInfo> <f>     UInt64  f

I would like program output to appear as:

<Field> <System.Reflection.RtFieldInfo> <a>     <Char[]>     Char[] a
<Field> <System.Reflection.RtFieldInfo> <b>     <UInt16>     UInt16 b
<Field> <System.Reflection.RtFieldInfo> <c>     <Char>       Char   c
<Field> <System.Reflection.RtFieldInfo> <d>     <Byte>       Byte   d
<Field> <System.Reflection.RtFieldInfo> <e>     <UInt32>     UInt32 e
<Field> <System.Reflection.RtFieldInfo> <f>     <UInt64>     UInt64 f
A: 

mi.Name is bringing back want you want, you jsut need to change your COnsole.WriteLine to print it again

ck
I suspect you might have misunderstood me. I'm wanting a list of the *datatypes*, not the field names. For example, I'm wanting a list [ char[], ushort, char, byte, uint, ulong ], a list that I can use programmatically, and not just display on the screeen.
JaysonFix
So, in your loop where you're writing them to the console, add the types to a List<Type> using Type.GetType(mi.Name)
ck
Sorry, instead of mi.Name you want mi.GetType()
ck
mi.GetType() returns System.Reflection.RtFieldInfo not the actual Type of the field.
Stan R.
+3  A: 

this is how I did it, you want the FieldType which actually returns a Type instance.

var members = typeof(TestMe).GetFields().Select(m => new 
                                         { 
                                             Name = m.Name, 
                                             MemType = m.MemberType, 
                                             RtField = m.GetType(), 
                                             Type = m.FieldType 
                                         });

foreach (var item in members)
    Console.WriteLine("<{0}> <{1}> <{2}> <{3}> {3} {2}", item.MemType, item.RtField, item.Name, item.Type, item.Type, item.Name);

public class TestMe
{
    public string A;
    public int B;
    public byte C;
    public decimal D;
}

This is the output:

<Field> <System.Reflection.RtFieldInfo> <A> <System.String> System.String A 
<Field> <System.Reflection.RtFieldInfo> <B> <System.Int32> System.Int32 B
<Field> <System.Reflection.RtFieldInfo> <C> <System.Byte> System.Byte C
<Field> <System.Reflection.RtFieldInfo> <D> <System.Decimal> System.Decimal D
Stan R.
Thank you for this idea. I had to modify it a bit to get it to work for me, but the idea came from you -- thanks again. FieldInfo [ ] fieldInfoArray = typeof(MyClass).GetFields() ; List <System.Type> fieldTypeList = new List <System.Type> ( ) ; foreach ( FieldInfo fieldInfo in fieldInfoArray ) fieldTypeList.Add ( fieldInfo.FieldType ) ; foreach ( System.Type type in fieldTypeList ) Console.WriteLine ( type ) ;
JaysonFix
no problem. btw if you just want a list. you could use the .ToList() method in Linq like so: List<Type> list = typeof(TestMe).GetFields().Select(m => m.FieldType).ToList();
Stan R.
+1  A: 

I'm not sure that MemberInfo has the information you want. You might want to look at GetFields() and the FieldInfo class, or GetProperties() and the PropertyInfo class.

GetMembers() returns all fields, properties and methods, so if your class contained these they would be enumerated as well.

GalacticCowboy
This is also a good idea ... thank you.
JaysonFix
A: 

You're looking for the Name property off of FieldType, which is available via FieldInfo. You'll need to cast MemberInfo to a FieldInfo first:

foreach (MemberInfo mi in theMemberInfoArray)
{
    if (mi.MemberType == MemberTypes.Field)
    {
        FieldInfo fi = mi as FieldInfo;
        Console.WriteLine(fi.FieldType.Name);
    }
}

Output:

Char[]
UInt16
Char
Byte
UInt32
UInt64
Jeremy Frey
Thanks! I wish I could accept multiple answers, since your idea is also a good one.
JaysonFix