General object debugger

I am trying to write a generic function with which I can pass an object, and will print all properties and values ​​in C #.

I tried many examples, for example, 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 objects that I want in debug / log files contain string [] properties. all of these examples output them 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 as shown below, with any values ​​that were set

 Name: Test Number: 3 Names[0]: Fred Names[1]: John Names[2]: Jimmy 

Thanks for any help =]

This is the class in which I used

 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 am going to use Log4Net with this class, and now on my mvc3 website I can call it when ViewModels will be serviced and sent to get comprehensive debugging when turned on.

+4
source share
1 answer

If you don't mind using Windows Forms, there is a PropertyGrid control 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 problem is that you are not looking inside the array. What you have to do is look at the type of each property. If this is an array type, then you need to pass the value to the object[] array, and then iterate over each element, and not just print the output of ToString() . You will also need to create a recursive algorithm that will look inside each property and treat it like an object that has properties that need to be repeated. If you need help with this, let me know.

+4
source

Source: https://habr.com/ru/post/1412895/


All Articles