{"id":4142,"date":"2020-10-14T15:15:21","date_gmt":"2020-10-14T14:15:21","guid":{"rendered":"https:\/\/solidt.eu\/site\/?p=4142"},"modified":"2022-07-25T08:32:07","modified_gmt":"2022-07-25T07:32:07","slug":"c-object-dumper","status":"publish","type":"post","link":"https:\/\/solidt.eu\/site\/c-object-dumper\/","title":{"rendered":"C# object dumper"},"content":{"rendered":"\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">using System;\nusing System.Collections.Generic;\nusing System.ComponentModel;\nusing System.Linq;\nusing System.Text;\n\npublic static class ObjectDumper\n{\n    public static string Dump(object obj, int level = 3) => DictionaryToString(ToDictionary(obj, level));\n\n    private static bool IsObject(object o) => o != null &amp;&amp; Type.GetTypeCode(o.GetType()) == TypeCode.Object;\n\n    private static bool IsNumeric(Type type)\n    {\n        if (type.IsEnum)\n            return false;\n        switch (Type.GetTypeCode(type))\n        {\n            case TypeCode.Byte:\n            case TypeCode.SByte:\n            case TypeCode.UInt16:\n            case TypeCode.UInt32:\n            case TypeCode.UInt64:\n            case TypeCode.Int16:\n            case TypeCode.Int32:\n            case TypeCode.Int64:\n            case TypeCode.Decimal:\n            case TypeCode.Double:\n            case TypeCode.Single:\n                return true;\n            case TypeCode.Object:\n                if (type.IsGenericType &amp;&amp; type.GetGenericTypeDefinition() == typeof(Nullable&lt;>))\n                {\n                    return IsNumeric(Nullable.GetUnderlyingType(type));\n                }\n                return false;\n            default:\n                return false;\n        }\n    }\n\n    private static string Repeat(string value, int count) => new StringBuilder(value.Length * count).Insert(0, value, count).ToString();\n\n    private static IDictionary&lt;string, object> ToDictionary(object source, int level = 3)\n    {\n        if (source == null) return null;\n        var dictionary = new Dictionary&lt;string, object>();\n        foreach (PropertyDescriptor property in TypeDescriptor.GetProperties(source))\n            AddPropertyToDictionary(property, source, dictionary, level);\n        return dictionary;\n    }\n\n    private static void AddPropertyToDictionary(PropertyDescriptor property, object source, Dictionary&lt;string, object> dictionary, int level)\n    {\n        object value = null;\n        try\n        {\n            value = property.GetValue(source);\n        }\n        catch\n        {\n            \/\/ ignore\n        }\n        if (value == null)\n        {\n            dictionary.Add(property.Name, null);\n            return;\n        }\n        if (IsObject(value) &amp;&amp; level > 0)\n        {\n            dictionary.Add(property.Name, ToDictionary(value, level - 1));\n            return;\n        }\n        dictionary.Add(property.Name, value);\n    }\n\n    private static string DictionaryToString(IDictionary&lt;string, object> dictionary, int level = 0)\n    {\n        var sb = new StringBuilder();\n        sb.AppendLine(\"{\");\n        var keys = dictionary.Keys.ToList();\n        keys.Sort();\n        var prefix = Repeat(\"   \", level);\n        foreach (var key in keys)\n        {\n            var value = dictionary[key];\n            if (value == null)\n            {\n                sb.AppendLine($\"{prefix}{key}: {value}\");\n                continue;\n            }\n\n            if (value is IDictionary&lt;string, object> d)\n            {\n                sb.AppendLine($\"{prefix}{key}: \" + DictionaryToString(d, level + 1));\n                continue;\n            }\n\n            if (IsNumeric(value.GetType()))\n                sb.AppendLine($\"{prefix}{key}: {value}\");\n            else\n                sb.AppendLine($\"{prefix}{key}: \\\"{value}\\\"\");\n        }\n        sb.Append($\"{prefix}\" + \"}\");\n        return sb.ToString();\n    }\n}<\/pre>\n","protected":false},"excerpt":{"rendered":"","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"inline_featured_image":false,"footnotes":""},"categories":[6,4,1],"tags":[],"class_list":["post-4142","post","type-post","status-publish","format-standard","hentry","category-dotnet","category-programming","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/posts\/4142","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/comments?post=4142"}],"version-history":[{"count":3,"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/posts\/4142\/revisions"}],"predecessor-version":[{"id":4145,"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/posts\/4142\/revisions\/4145"}],"wp:attachment":[{"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/media?parent=4142"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/categories?post=4142"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/tags?post=4142"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}