I wanted to print the contents of some objects, for debugging purposes. One option was to override my Class’s ToString method and simply use Console.WriteLine(myObject). I do this on a few classes, and suddenly I have to maintain all these ToString methods whenever I change their properties or fields.
All that extra work, just for some debug statements? I think not – I’d rather the computer do the work for me. After all, it always knows what properties my objects have. So I wrote a method for automatically generating a “pretty” snapshot of an object’s state. C# code follows.
Console.WriteLine(AutoString(DBNull.Value)); // DBNull { } Console.WriteLine(AutoString("A String", true)); // String // { // FirstChar: A // Length: 8 // m_firstChar: A // m_stringLength: 8 // } Console.WriteLine(AutoString(new Customer { Id = 12, Name = "Smith", Address = new Address { City = "Springfield" } })); // Customer // { // Address: TestApp.Address // Id: 12 // Name: Smith // Region: // } public static string AutoString(object obj, bool includeNonPublic = false) { if (obj == null) return "null"; Type type = obj.GetType(); BindingFlags flags = BindingFlags.Instance | BindingFlags.Public; if (includeNonPublic) flags = flags | BindingFlags.NonPublic; List<MemberInfo> members = type.GetProperties(flags) .Where(property => property.GetIndexParameters().Length == 0) .Cast<MemberInfo>() .Concat(type.GetFields(flags)) .OrderBy(member => member.Name) .ToList(); StringBuilder sb = new StringBuilder(); if (members.Count > 0) { sb.AppendLine(type.Name); sb.AppendLine("{"); int longest = members.Max(m => m.Name.Length); foreach (MemberInfo member in members) { sb.Append(" "); sb.Append(member.Name); sb.Append(":"); sb.Append(' ', longest - member.Name.Length + 1); sb.Append(GetValue(member as PropertyInfo, obj)); sb.Append(GetValue(member as FieldInfo, obj)); sb.AppendLine(); } sb.Append("}"); } else { sb.Append(type.Name); sb.Append(" { }"); } return sb.ToString(); } private static string GetValue(PropertyInfo property, object instance) { if (property == null) return null; var value = property.GetValue(instance, null); if (value == null) return null; return value.ToString(); } private static string GetValue(FieldInfo field, object instance) { if (field == null) return null; var value = field.GetValue(instance); if (value == null) return null; return value.ToString(); }