Search code examples
c#object-dumper

object dumper class


I'm looking for a class that can output an object and all its leaf values in a format similar to this:

User
  - Name: Gordon
  - Age : 60
  - WorkAddress
     - Street: 10 Downing Street
     - Town: London
     - Country: UK
  - HomeAddresses[0]
    ...
  - HomeAddresses[1]
    ...

(Or a clearer format). This would be equivalent to:

public class User
{
    public string Name { get;set; }
    public int Age { get;set; }
    public Address WorkAddress { get;set; }
    public List<Address> HomeAddresses { get;set; }
}

public class Address
{
    public string Street { get;set; }
    public string Town { get;set; }
    public string Country { get;set; }
}

A kind of string representation of the PropertyGrid control, minus having to implement a large set of designers for each type.

PHP has something that does this called var_dump. I don't want to use a watch, as this is for printing out.

Could anyone point me to something like this if it exists? Or, write one for a bounty.


Solution

  • The object dumper posted in sgmoore's link:

    //Copyright (C) Microsoft Corporation.  All rights reserved.
    
    using System;
    using System.IO;
    using System.Collections;
    using System.Collections.Generic;
    using System.Reflection;
    
    // See the ReadMe.html for additional information
    public class ObjectDumper {
    
        public static void Write(object element)
        {
            Write(element, 0);
        }
    
        public static void Write(object element, int depth)
        {
            Write(element, depth, Console.Out);
        }
    
        public static void Write(object element, int depth, TextWriter log)
        {
            ObjectDumper dumper = new ObjectDumper(depth);
            dumper.writer = log;
            dumper.WriteObject(null, element);
        }
    
        TextWriter writer;
        int pos;
        int level;
        int depth;
    
        private ObjectDumper(int depth)
        {
            this.depth = depth;
        }
    
        private void Write(string s)
        {
            if (s != null) {
                writer.Write(s);
                pos += s.Length;
            }
        }
    
        private void WriteIndent()
        {
            for (int i = 0; i < level; i++) writer.Write("  ");
        }
    
        private void WriteLine()
        {
            writer.WriteLine();
            pos = 0;
        }
    
        private void WriteTab()
        {
            Write("  ");
            while (pos % 8 != 0) Write(" ");
        }
    
        private void WriteObject(string prefix, object element)
        {
            if (element == null || element is ValueType || element is string) {
                WriteIndent();
                Write(prefix);
                WriteValue(element);
                WriteLine();
            }
            else {
                IEnumerable enumerableElement = element as IEnumerable;
                if (enumerableElement != null) {
                    foreach (object item in enumerableElement) {
                        if (item is IEnumerable && !(item is string)) {
                            WriteIndent();
                            Write(prefix);
                            Write("...");
                            WriteLine();
                            if (level < depth) {
                                level++;
                                WriteObject(prefix, item);
                                level--;
                            }
                        }
                        else {
                            WriteObject(prefix, item);
                        }
                    }
                }
                else {
                    MemberInfo[] members = element.GetType().GetMembers(BindingFlags.Public | BindingFlags.Instance);
                    WriteIndent();
                    Write(prefix);
                    bool propWritten = false;
                    foreach (MemberInfo m in members) {
                        FieldInfo f = m as FieldInfo;
                        PropertyInfo p = m as PropertyInfo;
                        if (f != null || p != null) {
                            if (propWritten) {
                                WriteTab();
                            }
                            else {
                                propWritten = true;
                            }
                            Write(m.Name);
                            Write("=");
                            Type t = f != null ? f.FieldType : p.PropertyType;
                            if (t.IsValueType || t == typeof(string)) {
                                WriteValue(f != null ? f.GetValue(element) : p.GetValue(element, null));
                            }
                            else {
                                if (typeof(IEnumerable).IsAssignableFrom(t)) {
                                    Write("...");
                                }
                                else {
                                    Write("{ }");
                                }
                            }
                        }
                    }
                    if (propWritten) WriteLine();
                    if (level < depth) {
                        foreach (MemberInfo m in members) {
                            FieldInfo f = m as FieldInfo;
                            PropertyInfo p = m as PropertyInfo;
                            if (f != null || p != null) {
                                Type t = f != null ? f.FieldType : p.PropertyType;
                                if (!(t.IsValueType || t == typeof(string))) {
                                    object value = f != null ? f.GetValue(element) : p.GetValue(element, null);
                                    if (value != null) {
                                        level++;
                                        WriteObject(m.Name + ": ", value);
                                        level--;
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    
        private void WriteValue(object o)
        {
            if (o == null) {
                Write("null");
            }
            else if (o is DateTime) {
                Write(((DateTime)o).ToShortDateString());
            }
            else if (o is ValueType || o is string) {
                Write(o.ToString());
            }
            else if (o is IEnumerable) {
                Write("...");
            }
            else {
                Write("{ }");
            }
        }
    }
    

    2015 Update

    YAML also serves this purpose quite well, this is how it can be done with YamlDotNet

    install-package YamlDotNet

        private static void DumpAsYaml(object o)
        {
            var stringBuilder = new StringBuilder();
            var serializer = new Serializer();
            serializer.Serialize(new IndentedTextWriter(new StringWriter(stringBuilder)), o);
            Console.WriteLine(stringBuilder);
        }