Reputation: 121
I'm trying to write a general function that i can pass an object to and it will print out all the properties and values in c#.
I've tried a lot of examples out there like this, and some others like
public void PrintProperties(object obj)
{
PrintProperties(obj, 0);
}
public void PrintProperties(object obj, int indent)
{
if (obj == null) return;
string indentString = new string(' ', indent);
Type objType = obj.GetType();
PropertyInfo[] properties = objType.GetProperties();
foreach (PropertyInfo property in properties)
{
object propValue = property.GetValue(obj, null);
if (property.PropertyType.Assembly == objType.Assembly)
{
Console.WriteLine("{0}{1}:", indentString, property.Name);
PrintProperties(propValue, indent + 2);
}
else
{
Console.WriteLine("{0}{1}: {2}", indentString, property.Name, propValue);
}
}
}
and
foreach (PropertyDescriptor descriptor in TypeDescriptor.GetProperties(obj))
{
string name = descriptor.Name;
object value = descriptor.GetValue(obj);
Console.WriteLine("{0}={1}", name, value);
}
but some of the objects i want in my debug / log files contain string[] properties. all of these examples output these as
System.String[]
if i had an object like
class Thing
{
public string Name { get; set; }
public int Number { get; set; }
public string[] Names { get; set; }
}
i would expect to see in the log like bellow with whatever values were set
Name: Test
Number: 3
Names[0]: Fred
Names[1]: John
Names[2]: Jimmy
Thank you for any help =]
This is the class i ended up using
class Descriptor
{
public void PrintProperties(object obj)
{
PrintProperties(obj, 0);
}
public void PrintProperties(object obj, int indent)
{
if (obj == null) return;
string indentString = new string(' ', indent);
Type objType = obj.GetType();
PropertyInfo[] properties = objType.GetProperties();
foreach (PropertyInfo property in properties)
{
object propValue = property.GetValue(obj, null);
if (propValue.GetType().IsArray)
{
object[] arrary = (object[]) propValue;
foreach (string value in arrary)
{
if (property.PropertyType.Assembly == objType.Assembly)
{
Console.WriteLine("{0}{1}:", indentString, property.Name);
PrintProperties(value, indent + 2);
}
else
{
Console.WriteLine("{0}{1}: {2}", indentString, property.Name, value);
}
}
continue;
}
if (property.PropertyType.Assembly == objType.Assembly)
{
Console.WriteLine("{0}{1}:", indentString, property.Name);
PrintProperties(propValue, indent + 2);
}
else
{
Console.WriteLine("{0}{1}: {2}", indentString, property.Name, propValue);
}
}
}
}
Now I'm going to use Log4Net with this class and now throughout my mvc3 site i can call this with ViewModels being served and posted to get a comprehensive debug when switched on
Upvotes: 4
Views: 328
Reputation: 209445
If you don't mind using Windows Forms, there's a control called a PropertyGrid
that basically does what you want: http://msdn.microsoft.com/en-us/library/system.windows.forms.propertygrid(v=vs.90).aspx
Now, for your specific problem, the issue is that you aren't looking inside the array. What you should do is look at the type of each property. If it's an array type, then you need to cast the value to an object[]
array and then iterate through each element, rather than simply printing the value's ToString()
output. You will also need to create a recursive algorithm that looks inside each property and treats it like an object that has properties to be iterated over. If you need help with that, let me know.
Upvotes: 4