Skip to content

Instantly share code, notes, and snippets.

@syaifulnizamyahya
Last active July 30, 2021 07:53
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save syaifulnizamyahya/e9b7d935f14940b236445508aab0320f to your computer and use it in GitHub Desktop.
Save syaifulnizamyahya/e9b7d935f14940b236445508aab0320f to your computer and use it in GitHub Desktop.
ObjectDumper for UWP. Use it to quickly get whats inside an object.
using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using System.Text;
using WinRTXamlToolkit.Common;
namespace ObjectDumper
{
//http://stackoverflow.com/questions/852181/c-printing-all-properties-of-an-object
//https://github.com/mcshaz/BlowTrial/blob/master/GenericToDataFile/ObjectDumper.cs
// How to use
// var dump = ObjectDumper.Dump(targetObject);
// WriteLine(dump);
public class ObjectDumper
{
private readonly int _depth;
private readonly Dictionary<object, int> _hashListOfFoundElements;
private readonly char _indentChar;
private readonly int _indentSize;
private readonly StringBuilder _stringBuilder;
private int _currentIndent;
private int _currentLine;
private ObjectDumper(int depth, int indentSize, char indentChar)
{
_depth = depth;
_indentSize = indentSize;
_indentChar = indentChar;
_stringBuilder = new StringBuilder();
_hashListOfFoundElements = new Dictionary<object, int>();
}
public static string Dump(object element, int depth = 4, int indentSize = 2, char indentChar = ' ')
{
var instance = new ObjectDumper(depth, indentSize, indentChar);
return instance.DumpElement(element, true);
}
private bool AlreadyDumped(object value)
{
if (value == null)
return false;
int lineNo;
if (_hashListOfFoundElements.TryGetValue(value, out lineNo))
{
Write("(reference already dumped - line:{0})", lineNo);
return true;
}
_hashListOfFoundElements.Add(value, _currentLine);
return false;
}
private string DumpElement(object element, bool isTopOfTree = false)
{
if (_currentIndent > _depth) { return null; }
if (element == null || element is string)
{
Write(FormatValue(element));
}
else if (element is ValueType)
{
Type objectType = element.GetType();
bool isWritten = false;
if (objectType.GetTypeInfo().IsGenericType)
{
Type baseType = objectType.GetGenericTypeDefinition();
if (baseType == typeof(KeyValuePair<,>))
{
isWritten = true;
Write("Key:");
_currentIndent++;
DumpElement(objectType.GetProperty("Key").GetValue(element, null));
_currentIndent--;
Write("Value:");
_currentIndent++;
DumpElement(objectType.GetProperty("Value").GetValue(element, null));
_currentIndent--;
}
}
if (!isWritten)
{
Write(FormatValue(element));
}
}
else
{
var enumerableElement = element as IEnumerable;
if (enumerableElement != null)
{
foreach (object item in enumerableElement)
{
if (item is IEnumerable && !(item is string))
{
_currentIndent++;
DumpElement(item);
_currentIndent--;
}
else
{
DumpElement(item);
}
}
}
else
{
Type objectType = element.GetType();
Write("{{{0}(HashCode:{1})}}", objectType.FullName, element.GetHashCode());
if (!AlreadyDumped(element))
{
_currentIndent++;
MemberInfo[] members = objectType.GetMembers(BindingFlags.Public | BindingFlags.Instance);
foreach (var memberInfo in members)
{
var fieldInfo = memberInfo as FieldInfo;
var propertyInfo = memberInfo as PropertyInfo;
if (fieldInfo == null && (propertyInfo == null || !propertyInfo.CanRead || propertyInfo.GetIndexParameters().Length > 0))
continue;
var type = fieldInfo != null ? fieldInfo.FieldType : propertyInfo.PropertyType;
object value;
try
{
value = fieldInfo != null
? fieldInfo.GetValue(element)
: propertyInfo.GetValue(element, null);
}
catch (Exception e)
{
Write("{0} failed with:{1}", memberInfo.Name, (e.GetBaseException() ?? e).Message);
continue;
}
if (type.GetTypeInfo().IsValueType || type == typeof(string))
{
Write("{0}: {1}", memberInfo.Name, FormatValue(value));
}
else
{
var isEnumerable = typeof(IEnumerable).IsAssignableFrom(type);
Write("{0}: {1}", memberInfo.Name, isEnumerable ? "..." : "{ }");
_currentIndent++;
DumpElement(value);
_currentIndent--;
}
}
_currentIndent--;
}
}
}
return isTopOfTree ? _stringBuilder.ToString() : null;
}
private string FormatValue(object o)
{
if (o == null)
return ("null");
if (o is DateTime)
return (((DateTime)o).ToShortDateString());
if (o is string)
return "\"" + (string)o + "\"";
if (o is char)
{
if (o.Equals('\0'))
{
return "''";
}
else
{
return "'" + (char)o + "'";
}
}
if (o is ValueType)
return (o.ToString());
if (o is IEnumerable)
return ("...");
return ("{ }");
}
private void Write(string value, params object[] args)
{
var space = new string(_indentChar, _currentIndent * _indentSize);
if (args != null)
value = string.Format(value, args);
_stringBuilder.AppendLine(space + value);
_currentLine++;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment