2

I came over this site (http://snipplr.com/view.php?codeview&id=17637), which illustrates use of reflection like this:

public class Person
    {
        public int Age { get; set; }
        public string Name { get; set; }
    }

   private void button2_Click_1(object sender, EventArgs e)
    {
        var person = new Person { Age = 30, Name = "Tony Montana" };
        var properties = typeof(Person).GetProperties();
        foreach (PropertyInfo property in properties)
        {
            Console.WriteLine("{0} = {1}", property.Name, property.GetValue(person, null));
        }
    }

The codesnippet above will give you: Age: 30 Name: Tony Montana

What if we added "Kid" to the class "AnotherPerson" like this

    public class Kid
    {
        public int KidAge { get; set; }
        public string KidName { get; set; }
    }
    public class AnotherPerson
    {
        public int Age { get; set; }
        public string Name { get; set; }
        public Kid Kid { get; set; }
    }

This snippet;

private void button3_Click(object sender, EventArgs e)
    {
        var anotherPerson = new AnotherPerson { Age = 30, Name = "Tony Montana", Kid = new Kid { KidAge = 10, KidName = "SomeName" } };
        var properties = typeof(AnotherPerson).GetProperties();
        foreach (PropertyInfo property in properties)
        {
            Console.WriteLine("{0} = {1}", property.Name, property.GetValue(anotherPerson, null));
        }
    }

gives me: Age: 30 Name: Tony Montana Kid: ProjectName.Form1+Kid

Not quite what I was looking for.... Could I use reflection to iterate trough "Kid" also? Suggestions?

Hanne Smith
  • 207
  • 2
  • 9
  • 2
    Do the same for `kid` object – I4V May 13 '13 at 13:43
  • 1
    Are you actually interested in some form of serialization, like JSON? http://json.codeplex.com/ – Tim S. May 13 '13 at 13:43
  • you will need to recursively call your outputting method and look to see if a property is an object i believe this question does it all: http://stackoverflow.com/questions/6196413/how-to-recursively-print-the-values-of-an-objects-properties-using-reflection –  May 13 '13 at 13:44

4 Answers4

0

Could have a helper method which is something like this?

public List<KeyValuePair<string, object>> GetPropertiesRecursive(object instance)
{
  List<KeyValuePair<string, object>> propValues = new List<KeyValuePair<string, object>>();
  foreach(PropertyInfo prop in instance.GetType().GetProperties())
  {
    propValues.Add(new KeyValuePair<string, object>(prop.Name, prop.GetValue(instance, null));
    propValues.AddRange(GetPropertiesRecursive(prop.GetValue(instance));
  }
}

Call as - GetPropertiesRecursive(anotherPerson)

LukeHennerley
  • 6,344
  • 1
  • 32
  • 50
0
    var anotherPerson = new AnotherPerson { Age = 30, Name = "Tony Montana", Kid = new Kid { KidAge = 10, KidName = "SomeName" } };
    var properties = typeof(AnotherPerson).GetProperties();
    foreach (PropertyInfo property in properties)
    {

        if (property.PropertyType == typeof(Kid)){
            var pp = typeof(Kid).GetProperties();
            Console.WriteLine("Kid:");
            foreach (PropertyInfo p in pp)
            {
                Console.WriteLine("\t{0} = {1}", p.Name, p.GetValue(anotherPerson.Kid, null));
            }
        }
        else
            Console.WriteLine("{0} = {1}", property.Name, property.GetValue(anotherPerson, null));
    }
Ahmed KRAIEM
  • 10,267
  • 4
  • 30
  • 33
  • What would happen if the OP added an `Adolescent` type to the `AnotherPerson`? The idea of reflection in this context is probably to make it as generic as possible for the future :) – LukeHennerley May 13 '13 at 13:52
  • 1
    This is far too inflexible. – James May 13 '13 at 13:52
  • True, for it to be _flexible_ you should treat primitive types, arrays, lists, dictionaries and indexed properties. – Ahmed KRAIEM May 13 '13 at 14:03
  • Not even that, it's too tightly coupled to the classes themselves. A good *flexible* solution would check whether the property itself is a class or whether it's a value type & deal with it in that way. – James May 13 '13 at 14:12
  • @James But it's not just whether the type is a value type or not; it's a question of whether the type overrides `ToString` in a way that provides as much information as you want. There are plenty of custom value types that won't do this, and plenty of custom classes that will. – Servy May 13 '13 at 14:16
  • @Servy well given the question (and example) the OP provided I doubt they are looking to take it to that level. The question was geared towards outputting basic value type properties, not gauging whether the type itself has a custom implementation of `ToString`. – James May 13 '13 at 14:26
0

The code loops through the properties and uses ToString (through the String.Format method that Console.WriteLine uses) to get the string representation of the property values.

If you want to change how the Kid property value is displayed, you basically have two options:

  1. Check the type of the property (property.PropertyType) in the reflection code, so that you can do something different for the Kid type.

  2. Override the ToString method in the Kid class, so that it returns whatever string you want to display as value.

Guffa
  • 687,336
  • 108
  • 737
  • 1,005
0

A method doing some recursion can get the values for properties within properties:

public static string GetProperties(object obj)
{
    var t = obj.GetType();
    var properties = t.GetProperties();
    var s = "";
    foreach (PropertyInfo property in properties)
    {
        object propValue = property.GetValue(obj, new object[0]);
        string propertyToString;
        if (t.GetMethod("ToString").DeclaringType != typeof(object))
            propertyToString = propValue.ToString();
        else if (typeof(IConvertible).IsAssignableFrom(property.PropertyType))
            propertyToString = Convert.ToString(propValue);
        else
            propertyToString = GetProperties(propValue);

        s += string.Format("'{0}' = '{1}'", property.Name, propertyToString);
    }
    return s;
}

If you had practical purposes in mind, JSON (or other) serialization may be more appropriate, e.g. using JSON.net would produce a similar string.

Tim S.
  • 55,448
  • 7
  • 96
  • 122