Search code examples
c#listreflectionpropertiesdump

Print object's List<> property value C#


I have an object type of e.g.:

Class
{
  public string Variable {get; set;}
  public List<AnotherClass> ListVariable {get; set;}
}

AnotherClass
{
  public string Variable {get; set;}
  public int IntVariable {get; set;}
}

I've tried several solutions (ObjectDumper, object.GetProperties) to print all the Class object values to screen; The problem concludes in inability to print List<AnotherClass>. Instead of all it's items I get only it's count property.

Tried solutions:

How to recursively print the values of an object's properties using reflection

Recursively Get Properties & Child Properties Of An Object

Finding all properties and subproperties of an object

and several more..

EDIT:

Ok, as I see, I probably didn't describe the problem well. I need to print all the object's properties and their values, when I don't know type of the object and it's properties. The listed solutions work fine, if object contains only simple properties. The problem shows up if one of the properties is List<>

I tried the following:

1)

private static void PrintObject(Object dataSource)
{
   foreach (PropertyDescriptor descriptor in TypeDescriptor.GetProperties(dataSource))
   {
      string name = descriptor.Name;
      object value = descriptor.GetValue(dataSource);

      RichTextBox.Text += name + ": " + value + "\n";

      PrintObject(control, value);
   }
}

Gives me the output:

CheckStatus: Performed

TextData: System.Collections.Generic.List`1[TextDataField]

Capacity: 16

Count: 15

but I was expecting all 15 item values here, not just list count.

2)

RichTextBox.Text = dataSource.DumpToString(); 

from http://objectdumper.codeplex.com/

Gives pretty much the same output.


Solution

  • "dumper" methods are the easiest and the most correct way of doing it, when you are in control of the source of the classes you want to look at. It's also the safest method because you can dump non-public stuff while preventing direct access to outsiders.

    Simplest way to achieve this is to override the ToString() method which Object provides to any type. This way, your code will be clean and readable.

    You might also do it through System.Reflection but it would be more complicated and provide no additional benefit. KISS is the keyword here.

    Like this (tested in LINQPad): NOTE public stuff is supposed to be capitalized, like this: public int Variable

    void Main()
    {
        Class myClassObj = new Class();
        myClassObj.Variable = 1;
        myClassObj.ListVariable = new List<AnotherClass>();
        myClassObj.ListVariable.Add(new AnotherClass{ Variable="some", IntVariable=2 });
    
        Console.WriteLine(myClassObj.ToString());
    }
    
    public class Class
    {
        public int Variable{get;set;}
        public List<AnotherClass> ListVariable {get;set;}
    
        public override string ToString()
        {
            return string.Join(", ", new string[]{ 
                string.Format("Variable= {0}", + this.Variable),
                string.Format("ListVariable= [{0}]", string.Join(", ", this.ListVariable))
            });
        }
    }
    
    public class AnotherClass
    {
        public string Variable{get;set;}
        public int IntVariable{get;set;}
    
        public override string ToString()
        {
            return string.Join(", ", new string[]{
                string.Format("Variable={0}", this.Variable),
                string.Format("IntVariable={0}", this.IntVariable)
            });
        }
    }