21

I'm constructing a method to take in an ArrayList(presumably full of objects) and then list all the fields(and their values) for each object in the ArrayList.

Currently my code is as follows:

public static void ListArrayListMembers(ArrayList list)
    {
        foreach (Object obj in list)
        {
            Type type = obj.GetType();
            string field = type.GetFields().ToString();
            Console.WriteLine(field);

        }
    }

Of course, I understand the immediate issue with this code: if it worked it'd only print one field per object in the ArrayList. I'll fix this later - right now I'm just curious how to get all of the public fields associated with an object.

Robert Harvey
  • 178,213
  • 47
  • 333
  • 501
junkforce
  • 543
  • 1
  • 4
  • 12

5 Answers5

35
foreach (Object obj in list) {
    Type type = obj.GetType();

    foreach (var f in type.GetFields().Where(f => f.IsPublic)) {
        Console.WriteLine(
            String.Format("Name: {0} Value: {1}", f.Name, f.GetValue(obj));
    }                           
}

Note that this code requires .NET 3.5 to work ;-)

Dave Markle
  • 95,573
  • 20
  • 147
  • 170
  • Nevermind. I like this technique better. I can just extrapolate this to get properties(and even methods) as well. Thanks a bunch! – junkforce Oct 26 '08 at 01:09
  • 1
    Thx for the .where condition Dave.. I know it is 10 years later but I like it. Straightforward.. only publics.. no need for getsetters.. and dont worry it still works with c# in VS 2017 .net 4.6.2 and core :p – Goodies Jan 05 '18 at 01:56
  • Note that type.GetFields() always only gets the public fields, so filtering for public fields isn't needed. – GreySage Sep 13 '21 at 18:57
10

You can obtain all the object Fields declared directly in the class with the BindingFlags:

GetFields(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly)

and all object Fields including inherited with:

GetFields(BindingFlags.Public | BindingFlags.Instance)
Jonathan Webb
  • 1,573
  • 1
  • 17
  • 26
5

Of course, another question would be "why have you got public fields?" - properties being preferable. As an abstraction, note that reflection isn't the only option: it is also possible for a type to expose it's properties on-the-fly at runtime (like how an untyped DataTable/DataView exposes columns as properties).

To support this (while also supporting simple objects), you would use TypeDescriptor:

        foreach(PropertyDescriptor prop in TypeDescriptor.GetProperties(obj))
        {
            Console.WriteLine("{0}={1}", prop.Name, prop.GetValue(obj));
        }

This also allows for numerous extensibility options - for example, vastly speeding up reflection (without changing any code).

Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
  • Pretty. This allowed me to make a general ToString() for an abstract superclass that shows two properties ("Key" and "Code" - was a database objects class) that most of its subclasses contain, without needing any specific information on said subclasses :) – Nyerguds Dec 19 '13 at 13:27
4
public static void ListArrayListMembers(ArrayList list)
{
    foreach (Object obj in list)
    {
        Type type = obj.GetType();
        Console.WriteLine("{0} -- ", type.Name);
        Console.WriteLine(" Properties: ");
        foreach (PropertyInfo prop in type.GetProperties())
        {
            Console.WriteLine("\t{0} {1} = {2}", prop.PropertyType.Name, 
                prop.Name, prop.GetValue(obj, null));
        }
        Console.WriteLine(" Fields: ");
        foreach (FieldInfo field in type.GetFields())
        {
            Console.WriteLine("\t{0} {1} = {2}", field.FieldType.Name, 
                field.Name, field.GetValue(obj));
        }
    }
}

I'd like to mention that looking for IsPublic in the fields is not necessary as type.GetFields() as defined by MSDN states:

Return Value - Type: System.Reflection.FieldInfo[]

An array of FieldInfo objects representing all the public fields defined for the current Type.

nyxtom
  • 2,919
  • 2
  • 23
  • 24
1
    static void ListArrayListMembers(ArrayList list)
    {
        foreach (object obj in list)
        {
            Type type = obj.GetType();
            foreach (FieldInfo field in type.GetFields(BindingFlags.Public))
            {
                Console.WriteLine(field.Name + " = " + field.GetValue(obj).ToString());
            }
        }
    }
Jon B
  • 51,025
  • 31
  • 133
  • 161