简体   繁体   中英

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

To aid in debugging some code I'm working on, I started to write a method to recursively print out the names and values of an object's properties. However, most of the objects contain nested types and I'd like to print their names and values too, but only on the types I have defined.

Here's an outline of what I have so far:

public void PrintProperties(object obj)
{
    if (obj == null)
        return;

    Propertyinfo[] properties = obj.GetType().GetProperties();

    foreach (PropertyInfo property in properties)
    {
        if ([property is a type I have defined])
        {
            PrintProperties([instance of property's type]);
        }
        else
        {
            Console.WriteLine("{0}: {1}", property.Name, property.GetValue(obj, null));
        }
    }

The parts between the braces are where I'm unsure.

Any help will be greatly appreciated.

The code below has an attempt at that. For "type I have defined" I chose to look at the types in the same assembly as the ones the type whose properties are being printed, but you'll need to update the logic if your types are defined in multiple assemblies.

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 && !property.PropertyType.IsEnum)
        {
            Console.WriteLine("{0}{1}:", indentString, property.Name);
            PrintProperties(propValue, indent + 2);
        }
        else
        {
            Console.WriteLine("{0}{1}: {2}", indentString, property.Name, propValue);
        }
    }
}

Is there any particular reason why you want to use reflection? Instead you can use JavaScriptSerializer like this:

var serializer = new System.Web.Script.Serialization.JavaScriptSerializer();
string json = serializer.Serialize(obj);
Console.WriteLine(json);

It will recursively include all properties in string, and throw exception in case if circular reference will appear.

Leverage from Leonid's answer , the below code is what I used to create a readable Json dump of any object. It ignores null field and add indentation for better view (especially good for SOAP objects).

public static string SerializeToLogJson(this object obj)
        {
            try
            {
                var json = JsonConvert.SerializeObject(obj,
                    Newtonsoft.Json.Formatting.None, 
                    new JsonSerializerSettings { 
                        NullValueHandling = NullValueHandling.Ignore,
                        Formatting = Formatting.Indented
                    });
                return json;
            }
            catch (Exception e)
            {
                log.ErrorFormat(e.Message, e);
                return "Cannot serialize: " + e.Message;
            }
        }

Newtonsoft library provides very simple functions to serialize any object to JSON. This is a much simpler solution.

Newtonsoft.Json.JsonConvert.SerializeObject(objToSerialize);

for example:

dynamic obj = new { x = 1, y = 2, z = "abc" };
string json = JsonConvert.SerializeObject(obj);
//'json' string value: {"x":1,"y":2,"z":"abc"}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM