What is the best way to dump entire objects to a log in C#?











up vote
99
down vote

favorite
44












So for viewing a current object's state at runtime, I really like what the Visual Studio Immediate window gives me. Just doing a simple



? objectname


Will give me a nicely formatted 'dump' of the object.



Is there an easy way to do this in code, so I can do something similar when logging?










share|improve this question
























  • In the end, I've used T.Dump quite a bit. It's a pretty solid solution -- you just need to be careful of recursion.
    – Dan Esparza
    Dec 1 '15 at 13:23










  • This is an old question, but comes out at the top of a lot of search hits. For future readers: See this vs extension. Worked great for me in VS2015.
    – Jesse Good
    Dec 6 '15 at 1:20















up vote
99
down vote

favorite
44












So for viewing a current object's state at runtime, I really like what the Visual Studio Immediate window gives me. Just doing a simple



? objectname


Will give me a nicely formatted 'dump' of the object.



Is there an easy way to do this in code, so I can do something similar when logging?










share|improve this question
























  • In the end, I've used T.Dump quite a bit. It's a pretty solid solution -- you just need to be careful of recursion.
    – Dan Esparza
    Dec 1 '15 at 13:23










  • This is an old question, but comes out at the top of a lot of search hits. For future readers: See this vs extension. Worked great for me in VS2015.
    – Jesse Good
    Dec 6 '15 at 1:20













up vote
99
down vote

favorite
44









up vote
99
down vote

favorite
44






44





So for viewing a current object's state at runtime, I really like what the Visual Studio Immediate window gives me. Just doing a simple



? objectname


Will give me a nicely formatted 'dump' of the object.



Is there an easy way to do this in code, so I can do something similar when logging?










share|improve this question















So for viewing a current object's state at runtime, I really like what the Visual Studio Immediate window gives me. Just doing a simple



? objectname


Will give me a nicely formatted 'dump' of the object.



Is there an easy way to do this in code, so I can do something similar when logging?







c# visual-studio debugging object logging






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Jan 18 at 4:07









Matas Vaitkevicius

32.3k15161171




32.3k15161171










asked Dec 11 '08 at 17:58









Dan Esparza

19.6k2488121




19.6k2488121












  • In the end, I've used T.Dump quite a bit. It's a pretty solid solution -- you just need to be careful of recursion.
    – Dan Esparza
    Dec 1 '15 at 13:23










  • This is an old question, but comes out at the top of a lot of search hits. For future readers: See this vs extension. Worked great for me in VS2015.
    – Jesse Good
    Dec 6 '15 at 1:20


















  • In the end, I've used T.Dump quite a bit. It's a pretty solid solution -- you just need to be careful of recursion.
    – Dan Esparza
    Dec 1 '15 at 13:23










  • This is an old question, but comes out at the top of a lot of search hits. For future readers: See this vs extension. Worked great for me in VS2015.
    – Jesse Good
    Dec 6 '15 at 1:20
















In the end, I've used T.Dump quite a bit. It's a pretty solid solution -- you just need to be careful of recursion.
– Dan Esparza
Dec 1 '15 at 13:23




In the end, I've used T.Dump quite a bit. It's a pretty solid solution -- you just need to be careful of recursion.
– Dan Esparza
Dec 1 '15 at 13:23












This is an old question, but comes out at the top of a lot of search hits. For future readers: See this vs extension. Worked great for me in VS2015.
– Jesse Good
Dec 6 '15 at 1:20




This is an old question, but comes out at the top of a lot of search hits. For future readers: See this vs extension. Worked great for me in VS2015.
– Jesse Good
Dec 6 '15 at 1:20












12 Answers
12






active

oldest

votes

















up vote
50
down vote



accepted










You could base something on the ObjectDumper code that ships with the Linq samples.

Have also a look at the answer of this related question to get a sample.






share|improve this answer























  • Wow -- great idea. Also, here is this idea as an extension method blogs.msdn.com/danielfe/archive/2005/09/22/473018.aspx
    – Dan Esparza
    Dec 11 '08 at 18:24










  • Doesn't seem to work for XmlDocuments...
    – John Hunter
    Jul 2 '09 at 13:42






  • 4




    It also doesn't work for arrays (it just displays the type and the length of the array, but doesn't print its contents).
    – Konrad Morawski
    Sep 20 '12 at 6:57






  • 3




    nuget package for ObjectDumper is now available. It also provides an extension method DumpToString and Dump to Object class. Handy.
    – IsmailS
    Jun 17 '15 at 9:43






  • 1




    w3wp.exe crashes when I attempt to use ObjectDumper like Request.DumpToString("aaa");
    – Paul
    May 2 '16 at 15:39




















up vote
39
down vote













For a larger object graph, I second the use of Json but with a slightly different strategy. First I have a static class that is easy to call and with a static method that wraps the Json conversion (note: could make this an extension method).



using Newtonsoft.Json;

public static class F
{
public static string Dump(object obj)
{
return JsonConvert.SerializeObject(obj);
}
}


Then in your Immediate Window,



var lookHere = F.Dump(myobj);


lookHere will auto-show up in the Locals window prepended with a $ or you can add a watch to it. On the right hand side of the Value column in the inspector, there is a magnifying glass with a dropdown caret beside it. Choose the dropdown caret and choose Json visualizer.



Screenshot of Visual Studio 2013 Locals window



I am using Visual Studio 2013.






share|improve this answer



















  • 2




    SerializeObj -> SerializeObject?
    – Wiseman
    Oct 27 '14 at 12:07










  • Brilliant, thank you. I cannot install debug tools for Visual Studio on my remote server, and this thing works extremely well in my asp.net mvc app.
    – Восилей
    Apr 23 at 17:45




















up vote
24
down vote













I'm certain there are better ways of doing this, but I have in the past used a method something like the following to serialize an object into a string that I can log:



  private string ObjectToXml(object output)
{
string objectAsXmlString;

System.Xml.Serialization.XmlSerializer xs = new System.Xml.Serialization.XmlSerializer(output.GetType());
using (System.IO.StringWriter sw = new System.IO.StringWriter())
{
try
{
xs.Serialize(sw, output);
objectAsXmlString = sw.ToString();
}
catch (Exception ex)
{
objectAsXmlString = ex.ToString();
}
}

return objectAsXmlString;
}


You'll see that the method might also return the exception rather than the serialized object, so you'll want to ensure that the objects you want to log are serializable.






share|improve this answer

















  • 2




    In the light of the features added to C# after you answered the question might be useful to point out that this implementation works nicely as an extension method. If applied to Object class and you reference the extension everywhere you need it, it could be a convenient way to call the function.
    – Nikita G.
    Nov 10 '13 at 9:14










  • I keep getting from this: Failed to access type 'System.__ComObject' failed. Noob to c#, would appreciate help.
    – GuySoft
    Oct 18 '14 at 18:50








  • 1




    @GuySoft I suspect one of the properties on your object, or the object itself, is not serializable.
    – Bernhard Hofmann
    Oct 20 '14 at 9:15










  • @BernhardHofmann Thanks will look in to it
    – GuySoft
    Oct 20 '14 at 12:35










  • @BernhardHofmann Yes, seems that way :-/
    – GuySoft
    Oct 23 '14 at 13:31


















up vote
17
down vote













I have a T.Dump() extension method that does exactly this, recursively dumps all properties of any type in a nice readable format.



Example usage:



var model = new TestModel();
Console.WriteLine(model.Dump());


and output:



{
Int: 1,
String: One,
DateTime: 2010-04-11,
Guid: c050437f6fcd46be9b2d0806a0860b3e,
EmptyIntList: ,
IntList:
[
1,
2,
3
],
StringList:
[
one,
two,
three
],
StringIntMap:
{
a: 1,
b: 2,
c: 3
}
}





share|improve this answer



















  • 1




    It doesn't work for fields. The OP was explicitly asking about "entire objects".
    – Konrad Morawski
    Sep 20 '12 at 7:04








  • 4




    He didn't say fields - he said entire objects, which includes fields. He also mentioned Visual Studio's Immediate Window feature as an example what of he wanted to achieve ("Just doing a simple ? objectname will give me a nicely formatted 'dump' of the object"). ? objectname prints out all the fields as well. This has been immensely helpful - one of my most used extension methods to date - I'm not questioning that it's useful, only that it dumps entire objects.
    – Konrad Morawski
    Sep 20 '12 at 8:24








  • 2




    @KonradMorawski Wrong entire objects means a recursive dump of the object, NOT that it includes fields, which can easily lead to infinite recursive loop. You shouldn't assume what others are implying. My answer is both relevant and helpful, your down vote + comment is not.
    – mythz
    Sep 20 '12 at 9:08








  • 1




    @mythz yes of course you need to prevent a stack overflow (eg. every Int32 field has a MaxValue field, which is an Int32 itself...), that's a good point, but it doesn't change the fact that objects - and certainly entire ones - consist of fields, too, not just properties. What's more (you did not address that one), ? objectname in the Immediate Window does display fields - without triggering an infinite loop. If that's about my downvote, I can withdraw it (if you let me by unlocking it, that is). I disagree in principle anyway.
    – Konrad Morawski
    Sep 20 '12 at 9:33






  • 2




    -1 for essentially a link-only answer, though it looks great if I could use it! Perhaps I'm blind, but I can't find source via that link; the two upload folders are empty. Is the code too long to include in the answer?
    – user565869
    Jul 14 '14 at 19:26


















up vote
14
down vote













You could use Visual Studio Immediate Window



Just paste this (change actual to your object name obviously):



Newtonsoft.Json.JsonConvert.SerializeObject(actual);


It should print object in JSON
enter image description here



You should be able to copy it over textmechanic text tool or notepad++ and replace escaped quotes (") with " and newlines (rn) with empty space, then remove double quotes (") from beginning and end and paste it to jsbeautifier to make it more readable.



UPDATE to OP's comment



public static class Dumper
{
public static void Dump(this object obj)
{
Console.WriteLine(Newtonsoft.Json.JsonConvert.SerializeObject(obj)); // your logger
}
}


this should allow you to dump any object.



Hope this saves you some time.






share|improve this answer























  • Thanks. Perhaps you didn't catch it in my original question, but I indicated that I already knew about the immediate window, and I wanted to do the same thing when logging in my app.
    – Dan Esparza
    Jun 23 '15 at 15:38










  • @DanEsparza Console.Log(Newtonsoft.Json.JsonConvert.SerializeObject(actual)); ? :) and yes I indeed missed it. This question comes up when you search google.co.uk/…
    – Matas Vaitkevicius
    Jun 23 '15 at 15:52








  • 1




    FYI, when you have a JSON string in a C# string, click on the spyglass icon to the right of the string and pick the Text Visualizer. It will bring up a window that shows a plain text version of the JSON string (not escaped quotes or rn).
    – Walter
    Aug 31 '16 at 1:00


















up vote
10
down vote













Here is a stupidly simple way to write a flat object, nicely formatted:



using Newtonsoft.Json.Linq;

Debug.WriteLine("The object is " + JObject.FromObject(theObjectToDump).ToString());


What's going on is that the object is first converted to a JSON internal representation by JObject.FromObject, and then converted to JSON string by ToString. (And of course a JSON string is a very nice representation of a simple object, especially since ToString will include newlines and indents.) The "ToString" is of course extraneous (as it's implied by using + to concat a string and an object), but I kinda like to specify it here.






share|improve this answer

















  • 3




    JsonConvert.SerializeObject(apprec,Formatting.Indented) for comfortable reading in log
    – Tertium
    Aug 23 '16 at 23:04




















up vote
4
down vote













You could use reflection and loop through all the object properties, then get their values and save them to the log. The formatting is really trivial (you could use t to indent an objects properties and its values):



MyObject
Property1 = value
Property2 = value2
OtherObject
OtherProperty = value ...





share|improve this answer




























    up vote
    3
    down vote













    What I like doing is overriding ToString() so that I get more useful output beyond the type name. This is handy in the debugger, you can see the information you want about an object without needing to expand it.






    share|improve this answer




























      up vote
      3
      down vote













      I found a library called ObjectPrinter which allows to easily dump objects and collections to strings (and more). It does exactly what I needed.






      share|improve this answer




























        up vote
        3
        down vote













        Following is another version that does the same thing (and handle nested properties), which I think is simpler (no dependencies on external libraries and can be modified easily to do things other than logging):



        public class ObjectDumper
        {
        public static string Dump(object obj)
        {
        return new ObjectDumper().DumpObject(obj);
        }

        StringBuilder _dumpBuilder = new StringBuilder();

        string DumpObject(object obj)
        {
        DumpObject(obj, 0);
        return _dumpBuilder.ToString();
        }

        void DumpObject(object obj, int nestingLevel = 0)
        {
        var nestingSpaces = "".PadLeft(nestingLevel * 4);

        if (obj == null)
        {
        _dumpBuilder.AppendFormat("{0}nulln", nestingSpaces);
        }
        else if (obj is string || obj.GetType().IsPrimitive)
        {
        _dumpBuilder.AppendFormat("{0}{1}n", nestingSpaces, obj);
        }
        else if (ImplementsDictionary(obj.GetType()))
        {
        using (var e = ((dynamic)obj).GetEnumerator())
        {
        var enumerator = (IEnumerator)e;
        while (enumerator.MoveNext())
        {
        dynamic p = enumerator.Current;

        var key = p.Key;
        var value = p.Value;
        _dumpBuilder.AppendFormat("{0}{1} ({2})n", nestingSpaces, key, value != null ? value.GetType().ToString() : "<null>");
        DumpObject(value, nestingLevel + 1);
        }
        }
        }
        else if (obj is IEnumerable)
        {
        foreach (dynamic p in obj as IEnumerable)
        {
        DumpObject(p, nestingLevel);
        }
        }
        else
        {
        foreach (PropertyDescriptor descriptor in TypeDescriptor.GetProperties(obj))
        {
        string name = descriptor.Name;
        object value = descriptor.GetValue(obj);

        _dumpBuilder.AppendFormat("{0}{1} ({2})n", nestingSpaces, name, value != null ? value.GetType().ToString() : "<null>");
        DumpObject(value, nestingLevel + 1);
        }
        }
        }

        bool ImplementsDictionary(Type t)
        {
        return t.GetInterfaces().Any(i => i.Name.Contains("IDictionary"));
        }
        }







        share|improve this answer



















        • 1




          this will die horribly if you have a Date property in your inner object ... just saying ...
          – Noctis
          Sep 7 '17 at 4:43


















        up vote
        2
        down vote













        You can write your own WriteLine method-



        public static void WriteLine<T>(T obj)
        {
        var t = typeof(T);
        var props = t.GetProperties();
        StringBuilder sb = new StringBuilder();
        foreach (var item in props)
        {
        sb.Append($"{item.Name}:{item.GetValue(obj,null)}; ");
        }
        sb.AppendLine();
        Console.WriteLine(sb.ToString());
        }


        Use it like-



        WriteLine(myObject);


        To write a collection we can use-



         var ifaces = t.GetInterfaces();
        if (ifaces.Any(o => o.Name.StartsWith("ICollection")))
        {

        dynamic lst = t.GetMethod("GetEnumerator").Invoke(obj, null);
        while (lst.MoveNext())
        {
        WriteLine(lst.Current);
        }
        }


        The method may look like-



         public static void WriteLine<T>(T obj)
        {
        var t = typeof(T);
        var ifaces = t.GetInterfaces();
        if (ifaces.Any(o => o.Name.StartsWith("ICollection")))
        {

        dynamic lst = t.GetMethod("GetEnumerator").Invoke(obj, null);
        while (lst.MoveNext())
        {
        WriteLine(lst.Current);
        }
        }
        else if (t.GetProperties().Any())
        {
        var props = t.GetProperties();
        StringBuilder sb = new StringBuilder();
        foreach (var item in props)
        {
        sb.Append($"{item.Name}:{item.GetValue(obj, null)}; ");
        }
        sb.AppendLine();
        Console.WriteLine(sb.ToString());
        }
        }


        Using if, else if and checking interfaces, attributes, base type, etc. and recursion (as this is a recursive method) in this way we may achieve an object dumper, but it is tedious for sure. Using the object dumper from Microsoft's LINQ Sample would save your time.






        share|improve this answer























        • Out of curiousity: How does this handle arrays or lists? Or properties that reference parent objects?
          – Dan Esparza
          Mar 1 '16 at 14:50










        • @DanEsparza Thanks to show me the way to be more specific.
          – Ariful Islam
          Mar 2 '16 at 6:33


















        up vote
        0
        down vote













        Based on @engineforce answer, I made this class that I'm using in a PCL project of a Xamarin Solution:



        /// <summary>
        /// Based on: https://stackoverflow.com/a/42264037/6155481
        /// </summary>
        public class ObjectDumper
        {
        public static string Dump(object obj)
        {
        return new ObjectDumper().DumpObject(obj);
        }

        StringBuilder _dumpBuilder = new StringBuilder();

        string DumpObject(object obj)
        {
        DumpObject(obj, 0);
        return _dumpBuilder.ToString();
        }

        void DumpObject(object obj, int nestingLevel)
        {
        var nestingSpaces = "".PadLeft(nestingLevel * 4);

        if (obj == null)
        {
        _dumpBuilder.AppendFormat("{0}nulln", nestingSpaces);
        }
        else if (obj is string || obj.GetType().GetTypeInfo().IsPrimitive || obj.GetType().GetTypeInfo().IsEnum)
        {
        _dumpBuilder.AppendFormat("{0}{1}n", nestingSpaces, obj);
        }
        else if (ImplementsDictionary(obj.GetType()))
        {
        using (var e = ((dynamic)obj).GetEnumerator())
        {
        var enumerator = (IEnumerator)e;
        while (enumerator.MoveNext())
        {
        dynamic p = enumerator.Current;

        var key = p.Key;
        var value = p.Value;
        _dumpBuilder.AppendFormat("{0}{1} ({2})n", nestingSpaces, key, value != null ? value.GetType().ToString() : "<null>");
        DumpObject(value, nestingLevel + 1);
        }
        }
        }
        else if (obj is IEnumerable)
        {
        foreach (dynamic p in obj as IEnumerable)
        {
        DumpObject(p, nestingLevel);
        }
        }
        else
        {
        foreach (PropertyInfo descriptor in obj.GetType().GetRuntimeProperties())
        {
        string name = descriptor.Name;
        object value = descriptor.GetValue(obj);

        _dumpBuilder.AppendFormat("{0}{1} ({2})n", nestingSpaces, name, value != null ? value.GetType().ToString() : "<null>");

        // TODO: Prevent recursion due to circular reference
        if (name == "Self" && HasBaseType(obj.GetType(), "NSObject"))
        {
        // In ObjC I need to break the recursion when I find the Self property
        // otherwise it will be an infinite recursion
        Console.WriteLine($"Found Self! {obj.GetType()}");
        }
        else
        {
        DumpObject(value, nestingLevel + 1);
        }
        }
        }
        }

        bool HasBaseType(Type type, string baseTypeName)
        {
        if (type == null) return false;

        string typeName = type.Name;

        if (baseTypeName == typeName) return true;

        return HasBaseType(type.GetTypeInfo().BaseType, baseTypeName);
        }

        bool ImplementsDictionary(Type t)
        {
        return t is IDictionary;
        }
        }





        share|improve this answer





















          Your Answer






          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "1"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f360277%2fwhat-is-the-best-way-to-dump-entire-objects-to-a-log-in-c%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          12 Answers
          12






          active

          oldest

          votes








          12 Answers
          12






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes








          up vote
          50
          down vote



          accepted










          You could base something on the ObjectDumper code that ships with the Linq samples.

          Have also a look at the answer of this related question to get a sample.






          share|improve this answer























          • Wow -- great idea. Also, here is this idea as an extension method blogs.msdn.com/danielfe/archive/2005/09/22/473018.aspx
            – Dan Esparza
            Dec 11 '08 at 18:24










          • Doesn't seem to work for XmlDocuments...
            – John Hunter
            Jul 2 '09 at 13:42






          • 4




            It also doesn't work for arrays (it just displays the type and the length of the array, but doesn't print its contents).
            – Konrad Morawski
            Sep 20 '12 at 6:57






          • 3




            nuget package for ObjectDumper is now available. It also provides an extension method DumpToString and Dump to Object class. Handy.
            – IsmailS
            Jun 17 '15 at 9:43






          • 1




            w3wp.exe crashes when I attempt to use ObjectDumper like Request.DumpToString("aaa");
            – Paul
            May 2 '16 at 15:39

















          up vote
          50
          down vote



          accepted










          You could base something on the ObjectDumper code that ships with the Linq samples.

          Have also a look at the answer of this related question to get a sample.






          share|improve this answer























          • Wow -- great idea. Also, here is this idea as an extension method blogs.msdn.com/danielfe/archive/2005/09/22/473018.aspx
            – Dan Esparza
            Dec 11 '08 at 18:24










          • Doesn't seem to work for XmlDocuments...
            – John Hunter
            Jul 2 '09 at 13:42






          • 4




            It also doesn't work for arrays (it just displays the type and the length of the array, but doesn't print its contents).
            – Konrad Morawski
            Sep 20 '12 at 6:57






          • 3




            nuget package for ObjectDumper is now available. It also provides an extension method DumpToString and Dump to Object class. Handy.
            – IsmailS
            Jun 17 '15 at 9:43






          • 1




            w3wp.exe crashes when I attempt to use ObjectDumper like Request.DumpToString("aaa");
            – Paul
            May 2 '16 at 15:39















          up vote
          50
          down vote



          accepted







          up vote
          50
          down vote



          accepted






          You could base something on the ObjectDumper code that ships with the Linq samples.

          Have also a look at the answer of this related question to get a sample.






          share|improve this answer














          You could base something on the ObjectDumper code that ships with the Linq samples.

          Have also a look at the answer of this related question to get a sample.







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited May 23 '17 at 12:26









          Community

          11




          11










          answered Dec 11 '08 at 18:07









          Mike Scott

          8,73153547




          8,73153547












          • Wow -- great idea. Also, here is this idea as an extension method blogs.msdn.com/danielfe/archive/2005/09/22/473018.aspx
            – Dan Esparza
            Dec 11 '08 at 18:24










          • Doesn't seem to work for XmlDocuments...
            – John Hunter
            Jul 2 '09 at 13:42






          • 4




            It also doesn't work for arrays (it just displays the type and the length of the array, but doesn't print its contents).
            – Konrad Morawski
            Sep 20 '12 at 6:57






          • 3




            nuget package for ObjectDumper is now available. It also provides an extension method DumpToString and Dump to Object class. Handy.
            – IsmailS
            Jun 17 '15 at 9:43






          • 1




            w3wp.exe crashes when I attempt to use ObjectDumper like Request.DumpToString("aaa");
            – Paul
            May 2 '16 at 15:39




















          • Wow -- great idea. Also, here is this idea as an extension method blogs.msdn.com/danielfe/archive/2005/09/22/473018.aspx
            – Dan Esparza
            Dec 11 '08 at 18:24










          • Doesn't seem to work for XmlDocuments...
            – John Hunter
            Jul 2 '09 at 13:42






          • 4




            It also doesn't work for arrays (it just displays the type and the length of the array, but doesn't print its contents).
            – Konrad Morawski
            Sep 20 '12 at 6:57






          • 3




            nuget package for ObjectDumper is now available. It also provides an extension method DumpToString and Dump to Object class. Handy.
            – IsmailS
            Jun 17 '15 at 9:43






          • 1




            w3wp.exe crashes when I attempt to use ObjectDumper like Request.DumpToString("aaa");
            – Paul
            May 2 '16 at 15:39


















          Wow -- great idea. Also, here is this idea as an extension method blogs.msdn.com/danielfe/archive/2005/09/22/473018.aspx
          – Dan Esparza
          Dec 11 '08 at 18:24




          Wow -- great idea. Also, here is this idea as an extension method blogs.msdn.com/danielfe/archive/2005/09/22/473018.aspx
          – Dan Esparza
          Dec 11 '08 at 18:24












          Doesn't seem to work for XmlDocuments...
          – John Hunter
          Jul 2 '09 at 13:42




          Doesn't seem to work for XmlDocuments...
          – John Hunter
          Jul 2 '09 at 13:42




          4




          4




          It also doesn't work for arrays (it just displays the type and the length of the array, but doesn't print its contents).
          – Konrad Morawski
          Sep 20 '12 at 6:57




          It also doesn't work for arrays (it just displays the type and the length of the array, but doesn't print its contents).
          – Konrad Morawski
          Sep 20 '12 at 6:57




          3




          3




          nuget package for ObjectDumper is now available. It also provides an extension method DumpToString and Dump to Object class. Handy.
          – IsmailS
          Jun 17 '15 at 9:43




          nuget package for ObjectDumper is now available. It also provides an extension method DumpToString and Dump to Object class. Handy.
          – IsmailS
          Jun 17 '15 at 9:43




          1




          1




          w3wp.exe crashes when I attempt to use ObjectDumper like Request.DumpToString("aaa");
          – Paul
          May 2 '16 at 15:39






          w3wp.exe crashes when I attempt to use ObjectDumper like Request.DumpToString("aaa");
          – Paul
          May 2 '16 at 15:39














          up vote
          39
          down vote













          For a larger object graph, I second the use of Json but with a slightly different strategy. First I have a static class that is easy to call and with a static method that wraps the Json conversion (note: could make this an extension method).



          using Newtonsoft.Json;

          public static class F
          {
          public static string Dump(object obj)
          {
          return JsonConvert.SerializeObject(obj);
          }
          }


          Then in your Immediate Window,



          var lookHere = F.Dump(myobj);


          lookHere will auto-show up in the Locals window prepended with a $ or you can add a watch to it. On the right hand side of the Value column in the inspector, there is a magnifying glass with a dropdown caret beside it. Choose the dropdown caret and choose Json visualizer.



          Screenshot of Visual Studio 2013 Locals window



          I am using Visual Studio 2013.






          share|improve this answer



















          • 2




            SerializeObj -> SerializeObject?
            – Wiseman
            Oct 27 '14 at 12:07










          • Brilliant, thank you. I cannot install debug tools for Visual Studio on my remote server, and this thing works extremely well in my asp.net mvc app.
            – Восилей
            Apr 23 at 17:45

















          up vote
          39
          down vote













          For a larger object graph, I second the use of Json but with a slightly different strategy. First I have a static class that is easy to call and with a static method that wraps the Json conversion (note: could make this an extension method).



          using Newtonsoft.Json;

          public static class F
          {
          public static string Dump(object obj)
          {
          return JsonConvert.SerializeObject(obj);
          }
          }


          Then in your Immediate Window,



          var lookHere = F.Dump(myobj);


          lookHere will auto-show up in the Locals window prepended with a $ or you can add a watch to it. On the right hand side of the Value column in the inspector, there is a magnifying glass with a dropdown caret beside it. Choose the dropdown caret and choose Json visualizer.



          Screenshot of Visual Studio 2013 Locals window



          I am using Visual Studio 2013.






          share|improve this answer



















          • 2




            SerializeObj -> SerializeObject?
            – Wiseman
            Oct 27 '14 at 12:07










          • Brilliant, thank you. I cannot install debug tools for Visual Studio on my remote server, and this thing works extremely well in my asp.net mvc app.
            – Восилей
            Apr 23 at 17:45















          up vote
          39
          down vote










          up vote
          39
          down vote









          For a larger object graph, I second the use of Json but with a slightly different strategy. First I have a static class that is easy to call and with a static method that wraps the Json conversion (note: could make this an extension method).



          using Newtonsoft.Json;

          public static class F
          {
          public static string Dump(object obj)
          {
          return JsonConvert.SerializeObject(obj);
          }
          }


          Then in your Immediate Window,



          var lookHere = F.Dump(myobj);


          lookHere will auto-show up in the Locals window prepended with a $ or you can add a watch to it. On the right hand side of the Value column in the inspector, there is a magnifying glass with a dropdown caret beside it. Choose the dropdown caret and choose Json visualizer.



          Screenshot of Visual Studio 2013 Locals window



          I am using Visual Studio 2013.






          share|improve this answer














          For a larger object graph, I second the use of Json but with a slightly different strategy. First I have a static class that is easy to call and with a static method that wraps the Json conversion (note: could make this an extension method).



          using Newtonsoft.Json;

          public static class F
          {
          public static string Dump(object obj)
          {
          return JsonConvert.SerializeObject(obj);
          }
          }


          Then in your Immediate Window,



          var lookHere = F.Dump(myobj);


          lookHere will auto-show up in the Locals window prepended with a $ or you can add a watch to it. On the right hand side of the Value column in the inspector, there is a magnifying glass with a dropdown caret beside it. Choose the dropdown caret and choose Json visualizer.



          Screenshot of Visual Studio 2013 Locals window



          I am using Visual Studio 2013.







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Oct 27 '14 at 21:32

























          answered Oct 3 '14 at 15:14









          Jason

          3,5802437




          3,5802437








          • 2




            SerializeObj -> SerializeObject?
            – Wiseman
            Oct 27 '14 at 12:07










          • Brilliant, thank you. I cannot install debug tools for Visual Studio on my remote server, and this thing works extremely well in my asp.net mvc app.
            – Восилей
            Apr 23 at 17:45
















          • 2




            SerializeObj -> SerializeObject?
            – Wiseman
            Oct 27 '14 at 12:07










          • Brilliant, thank you. I cannot install debug tools for Visual Studio on my remote server, and this thing works extremely well in my asp.net mvc app.
            – Восилей
            Apr 23 at 17:45










          2




          2




          SerializeObj -> SerializeObject?
          – Wiseman
          Oct 27 '14 at 12:07




          SerializeObj -> SerializeObject?
          – Wiseman
          Oct 27 '14 at 12:07












          Brilliant, thank you. I cannot install debug tools for Visual Studio on my remote server, and this thing works extremely well in my asp.net mvc app.
          – Восилей
          Apr 23 at 17:45






          Brilliant, thank you. I cannot install debug tools for Visual Studio on my remote server, and this thing works extremely well in my asp.net mvc app.
          – Восилей
          Apr 23 at 17:45












          up vote
          24
          down vote













          I'm certain there are better ways of doing this, but I have in the past used a method something like the following to serialize an object into a string that I can log:



            private string ObjectToXml(object output)
          {
          string objectAsXmlString;

          System.Xml.Serialization.XmlSerializer xs = new System.Xml.Serialization.XmlSerializer(output.GetType());
          using (System.IO.StringWriter sw = new System.IO.StringWriter())
          {
          try
          {
          xs.Serialize(sw, output);
          objectAsXmlString = sw.ToString();
          }
          catch (Exception ex)
          {
          objectAsXmlString = ex.ToString();
          }
          }

          return objectAsXmlString;
          }


          You'll see that the method might also return the exception rather than the serialized object, so you'll want to ensure that the objects you want to log are serializable.






          share|improve this answer

















          • 2




            In the light of the features added to C# after you answered the question might be useful to point out that this implementation works nicely as an extension method. If applied to Object class and you reference the extension everywhere you need it, it could be a convenient way to call the function.
            – Nikita G.
            Nov 10 '13 at 9:14










          • I keep getting from this: Failed to access type 'System.__ComObject' failed. Noob to c#, would appreciate help.
            – GuySoft
            Oct 18 '14 at 18:50








          • 1




            @GuySoft I suspect one of the properties on your object, or the object itself, is not serializable.
            – Bernhard Hofmann
            Oct 20 '14 at 9:15










          • @BernhardHofmann Thanks will look in to it
            – GuySoft
            Oct 20 '14 at 12:35










          • @BernhardHofmann Yes, seems that way :-/
            – GuySoft
            Oct 23 '14 at 13:31















          up vote
          24
          down vote













          I'm certain there are better ways of doing this, but I have in the past used a method something like the following to serialize an object into a string that I can log:



            private string ObjectToXml(object output)
          {
          string objectAsXmlString;

          System.Xml.Serialization.XmlSerializer xs = new System.Xml.Serialization.XmlSerializer(output.GetType());
          using (System.IO.StringWriter sw = new System.IO.StringWriter())
          {
          try
          {
          xs.Serialize(sw, output);
          objectAsXmlString = sw.ToString();
          }
          catch (Exception ex)
          {
          objectAsXmlString = ex.ToString();
          }
          }

          return objectAsXmlString;
          }


          You'll see that the method might also return the exception rather than the serialized object, so you'll want to ensure that the objects you want to log are serializable.






          share|improve this answer

















          • 2




            In the light of the features added to C# after you answered the question might be useful to point out that this implementation works nicely as an extension method. If applied to Object class and you reference the extension everywhere you need it, it could be a convenient way to call the function.
            – Nikita G.
            Nov 10 '13 at 9:14










          • I keep getting from this: Failed to access type 'System.__ComObject' failed. Noob to c#, would appreciate help.
            – GuySoft
            Oct 18 '14 at 18:50








          • 1




            @GuySoft I suspect one of the properties on your object, or the object itself, is not serializable.
            – Bernhard Hofmann
            Oct 20 '14 at 9:15










          • @BernhardHofmann Thanks will look in to it
            – GuySoft
            Oct 20 '14 at 12:35










          • @BernhardHofmann Yes, seems that way :-/
            – GuySoft
            Oct 23 '14 at 13:31













          up vote
          24
          down vote










          up vote
          24
          down vote









          I'm certain there are better ways of doing this, but I have in the past used a method something like the following to serialize an object into a string that I can log:



            private string ObjectToXml(object output)
          {
          string objectAsXmlString;

          System.Xml.Serialization.XmlSerializer xs = new System.Xml.Serialization.XmlSerializer(output.GetType());
          using (System.IO.StringWriter sw = new System.IO.StringWriter())
          {
          try
          {
          xs.Serialize(sw, output);
          objectAsXmlString = sw.ToString();
          }
          catch (Exception ex)
          {
          objectAsXmlString = ex.ToString();
          }
          }

          return objectAsXmlString;
          }


          You'll see that the method might also return the exception rather than the serialized object, so you'll want to ensure that the objects you want to log are serializable.






          share|improve this answer












          I'm certain there are better ways of doing this, but I have in the past used a method something like the following to serialize an object into a string that I can log:



            private string ObjectToXml(object output)
          {
          string objectAsXmlString;

          System.Xml.Serialization.XmlSerializer xs = new System.Xml.Serialization.XmlSerializer(output.GetType());
          using (System.IO.StringWriter sw = new System.IO.StringWriter())
          {
          try
          {
          xs.Serialize(sw, output);
          objectAsXmlString = sw.ToString();
          }
          catch (Exception ex)
          {
          objectAsXmlString = ex.ToString();
          }
          }

          return objectAsXmlString;
          }


          You'll see that the method might also return the exception rather than the serialized object, so you'll want to ensure that the objects you want to log are serializable.







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Dec 11 '08 at 18:08









          Bernhard Hofmann

          6,912115277




          6,912115277








          • 2




            In the light of the features added to C# after you answered the question might be useful to point out that this implementation works nicely as an extension method. If applied to Object class and you reference the extension everywhere you need it, it could be a convenient way to call the function.
            – Nikita G.
            Nov 10 '13 at 9:14










          • I keep getting from this: Failed to access type 'System.__ComObject' failed. Noob to c#, would appreciate help.
            – GuySoft
            Oct 18 '14 at 18:50








          • 1




            @GuySoft I suspect one of the properties on your object, or the object itself, is not serializable.
            – Bernhard Hofmann
            Oct 20 '14 at 9:15










          • @BernhardHofmann Thanks will look in to it
            – GuySoft
            Oct 20 '14 at 12:35










          • @BernhardHofmann Yes, seems that way :-/
            – GuySoft
            Oct 23 '14 at 13:31














          • 2




            In the light of the features added to C# after you answered the question might be useful to point out that this implementation works nicely as an extension method. If applied to Object class and you reference the extension everywhere you need it, it could be a convenient way to call the function.
            – Nikita G.
            Nov 10 '13 at 9:14










          • I keep getting from this: Failed to access type 'System.__ComObject' failed. Noob to c#, would appreciate help.
            – GuySoft
            Oct 18 '14 at 18:50








          • 1




            @GuySoft I suspect one of the properties on your object, or the object itself, is not serializable.
            – Bernhard Hofmann
            Oct 20 '14 at 9:15










          • @BernhardHofmann Thanks will look in to it
            – GuySoft
            Oct 20 '14 at 12:35










          • @BernhardHofmann Yes, seems that way :-/
            – GuySoft
            Oct 23 '14 at 13:31








          2




          2




          In the light of the features added to C# after you answered the question might be useful to point out that this implementation works nicely as an extension method. If applied to Object class and you reference the extension everywhere you need it, it could be a convenient way to call the function.
          – Nikita G.
          Nov 10 '13 at 9:14




          In the light of the features added to C# after you answered the question might be useful to point out that this implementation works nicely as an extension method. If applied to Object class and you reference the extension everywhere you need it, it could be a convenient way to call the function.
          – Nikita G.
          Nov 10 '13 at 9:14












          I keep getting from this: Failed to access type 'System.__ComObject' failed. Noob to c#, would appreciate help.
          – GuySoft
          Oct 18 '14 at 18:50






          I keep getting from this: Failed to access type 'System.__ComObject' failed. Noob to c#, would appreciate help.
          – GuySoft
          Oct 18 '14 at 18:50






          1




          1




          @GuySoft I suspect one of the properties on your object, or the object itself, is not serializable.
          – Bernhard Hofmann
          Oct 20 '14 at 9:15




          @GuySoft I suspect one of the properties on your object, or the object itself, is not serializable.
          – Bernhard Hofmann
          Oct 20 '14 at 9:15












          @BernhardHofmann Thanks will look in to it
          – GuySoft
          Oct 20 '14 at 12:35




          @BernhardHofmann Thanks will look in to it
          – GuySoft
          Oct 20 '14 at 12:35












          @BernhardHofmann Yes, seems that way :-/
          – GuySoft
          Oct 23 '14 at 13:31




          @BernhardHofmann Yes, seems that way :-/
          – GuySoft
          Oct 23 '14 at 13:31










          up vote
          17
          down vote













          I have a T.Dump() extension method that does exactly this, recursively dumps all properties of any type in a nice readable format.



          Example usage:



          var model = new TestModel();
          Console.WriteLine(model.Dump());


          and output:



          {
          Int: 1,
          String: One,
          DateTime: 2010-04-11,
          Guid: c050437f6fcd46be9b2d0806a0860b3e,
          EmptyIntList: ,
          IntList:
          [
          1,
          2,
          3
          ],
          StringList:
          [
          one,
          two,
          three
          ],
          StringIntMap:
          {
          a: 1,
          b: 2,
          c: 3
          }
          }





          share|improve this answer



















          • 1




            It doesn't work for fields. The OP was explicitly asking about "entire objects".
            – Konrad Morawski
            Sep 20 '12 at 7:04








          • 4




            He didn't say fields - he said entire objects, which includes fields. He also mentioned Visual Studio's Immediate Window feature as an example what of he wanted to achieve ("Just doing a simple ? objectname will give me a nicely formatted 'dump' of the object"). ? objectname prints out all the fields as well. This has been immensely helpful - one of my most used extension methods to date - I'm not questioning that it's useful, only that it dumps entire objects.
            – Konrad Morawski
            Sep 20 '12 at 8:24








          • 2




            @KonradMorawski Wrong entire objects means a recursive dump of the object, NOT that it includes fields, which can easily lead to infinite recursive loop. You shouldn't assume what others are implying. My answer is both relevant and helpful, your down vote + comment is not.
            – mythz
            Sep 20 '12 at 9:08








          • 1




            @mythz yes of course you need to prevent a stack overflow (eg. every Int32 field has a MaxValue field, which is an Int32 itself...), that's a good point, but it doesn't change the fact that objects - and certainly entire ones - consist of fields, too, not just properties. What's more (you did not address that one), ? objectname in the Immediate Window does display fields - without triggering an infinite loop. If that's about my downvote, I can withdraw it (if you let me by unlocking it, that is). I disagree in principle anyway.
            – Konrad Morawski
            Sep 20 '12 at 9:33






          • 2




            -1 for essentially a link-only answer, though it looks great if I could use it! Perhaps I'm blind, but I can't find source via that link; the two upload folders are empty. Is the code too long to include in the answer?
            – user565869
            Jul 14 '14 at 19:26















          up vote
          17
          down vote













          I have a T.Dump() extension method that does exactly this, recursively dumps all properties of any type in a nice readable format.



          Example usage:



          var model = new TestModel();
          Console.WriteLine(model.Dump());


          and output:



          {
          Int: 1,
          String: One,
          DateTime: 2010-04-11,
          Guid: c050437f6fcd46be9b2d0806a0860b3e,
          EmptyIntList: ,
          IntList:
          [
          1,
          2,
          3
          ],
          StringList:
          [
          one,
          two,
          three
          ],
          StringIntMap:
          {
          a: 1,
          b: 2,
          c: 3
          }
          }





          share|improve this answer



















          • 1




            It doesn't work for fields. The OP was explicitly asking about "entire objects".
            – Konrad Morawski
            Sep 20 '12 at 7:04








          • 4




            He didn't say fields - he said entire objects, which includes fields. He also mentioned Visual Studio's Immediate Window feature as an example what of he wanted to achieve ("Just doing a simple ? objectname will give me a nicely formatted 'dump' of the object"). ? objectname prints out all the fields as well. This has been immensely helpful - one of my most used extension methods to date - I'm not questioning that it's useful, only that it dumps entire objects.
            – Konrad Morawski
            Sep 20 '12 at 8:24








          • 2




            @KonradMorawski Wrong entire objects means a recursive dump of the object, NOT that it includes fields, which can easily lead to infinite recursive loop. You shouldn't assume what others are implying. My answer is both relevant and helpful, your down vote + comment is not.
            – mythz
            Sep 20 '12 at 9:08








          • 1




            @mythz yes of course you need to prevent a stack overflow (eg. every Int32 field has a MaxValue field, which is an Int32 itself...), that's a good point, but it doesn't change the fact that objects - and certainly entire ones - consist of fields, too, not just properties. What's more (you did not address that one), ? objectname in the Immediate Window does display fields - without triggering an infinite loop. If that's about my downvote, I can withdraw it (if you let me by unlocking it, that is). I disagree in principle anyway.
            – Konrad Morawski
            Sep 20 '12 at 9:33






          • 2




            -1 for essentially a link-only answer, though it looks great if I could use it! Perhaps I'm blind, but I can't find source via that link; the two upload folders are empty. Is the code too long to include in the answer?
            – user565869
            Jul 14 '14 at 19:26













          up vote
          17
          down vote










          up vote
          17
          down vote









          I have a T.Dump() extension method that does exactly this, recursively dumps all properties of any type in a nice readable format.



          Example usage:



          var model = new TestModel();
          Console.WriteLine(model.Dump());


          and output:



          {
          Int: 1,
          String: One,
          DateTime: 2010-04-11,
          Guid: c050437f6fcd46be9b2d0806a0860b3e,
          EmptyIntList: ,
          IntList:
          [
          1,
          2,
          3
          ],
          StringList:
          [
          one,
          two,
          three
          ],
          StringIntMap:
          {
          a: 1,
          b: 2,
          c: 3
          }
          }





          share|improve this answer














          I have a T.Dump() extension method that does exactly this, recursively dumps all properties of any type in a nice readable format.



          Example usage:



          var model = new TestModel();
          Console.WriteLine(model.Dump());


          and output:



          {
          Int: 1,
          String: One,
          DateTime: 2010-04-11,
          Guid: c050437f6fcd46be9b2d0806a0860b3e,
          EmptyIntList: ,
          IntList:
          [
          1,
          2,
          3
          ],
          StringList:
          [
          one,
          two,
          three
          ],
          StringIntMap:
          {
          a: 1,
          b: 2,
          c: 3
          }
          }






          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited May 17 '11 at 15:00

























          answered Aug 18 '10 at 16:04









          mythz

          117k14193332




          117k14193332








          • 1




            It doesn't work for fields. The OP was explicitly asking about "entire objects".
            – Konrad Morawski
            Sep 20 '12 at 7:04








          • 4




            He didn't say fields - he said entire objects, which includes fields. He also mentioned Visual Studio's Immediate Window feature as an example what of he wanted to achieve ("Just doing a simple ? objectname will give me a nicely formatted 'dump' of the object"). ? objectname prints out all the fields as well. This has been immensely helpful - one of my most used extension methods to date - I'm not questioning that it's useful, only that it dumps entire objects.
            – Konrad Morawski
            Sep 20 '12 at 8:24








          • 2




            @KonradMorawski Wrong entire objects means a recursive dump of the object, NOT that it includes fields, which can easily lead to infinite recursive loop. You shouldn't assume what others are implying. My answer is both relevant and helpful, your down vote + comment is not.
            – mythz
            Sep 20 '12 at 9:08








          • 1




            @mythz yes of course you need to prevent a stack overflow (eg. every Int32 field has a MaxValue field, which is an Int32 itself...), that's a good point, but it doesn't change the fact that objects - and certainly entire ones - consist of fields, too, not just properties. What's more (you did not address that one), ? objectname in the Immediate Window does display fields - without triggering an infinite loop. If that's about my downvote, I can withdraw it (if you let me by unlocking it, that is). I disagree in principle anyway.
            – Konrad Morawski
            Sep 20 '12 at 9:33






          • 2




            -1 for essentially a link-only answer, though it looks great if I could use it! Perhaps I'm blind, but I can't find source via that link; the two upload folders are empty. Is the code too long to include in the answer?
            – user565869
            Jul 14 '14 at 19:26














          • 1




            It doesn't work for fields. The OP was explicitly asking about "entire objects".
            – Konrad Morawski
            Sep 20 '12 at 7:04








          • 4




            He didn't say fields - he said entire objects, which includes fields. He also mentioned Visual Studio's Immediate Window feature as an example what of he wanted to achieve ("Just doing a simple ? objectname will give me a nicely formatted 'dump' of the object"). ? objectname prints out all the fields as well. This has been immensely helpful - one of my most used extension methods to date - I'm not questioning that it's useful, only that it dumps entire objects.
            – Konrad Morawski
            Sep 20 '12 at 8:24








          • 2




            @KonradMorawski Wrong entire objects means a recursive dump of the object, NOT that it includes fields, which can easily lead to infinite recursive loop. You shouldn't assume what others are implying. My answer is both relevant and helpful, your down vote + comment is not.
            – mythz
            Sep 20 '12 at 9:08








          • 1




            @mythz yes of course you need to prevent a stack overflow (eg. every Int32 field has a MaxValue field, which is an Int32 itself...), that's a good point, but it doesn't change the fact that objects - and certainly entire ones - consist of fields, too, not just properties. What's more (you did not address that one), ? objectname in the Immediate Window does display fields - without triggering an infinite loop. If that's about my downvote, I can withdraw it (if you let me by unlocking it, that is). I disagree in principle anyway.
            – Konrad Morawski
            Sep 20 '12 at 9:33






          • 2




            -1 for essentially a link-only answer, though it looks great if I could use it! Perhaps I'm blind, but I can't find source via that link; the two upload folders are empty. Is the code too long to include in the answer?
            – user565869
            Jul 14 '14 at 19:26








          1




          1




          It doesn't work for fields. The OP was explicitly asking about "entire objects".
          – Konrad Morawski
          Sep 20 '12 at 7:04






          It doesn't work for fields. The OP was explicitly asking about "entire objects".
          – Konrad Morawski
          Sep 20 '12 at 7:04






          4




          4




          He didn't say fields - he said entire objects, which includes fields. He also mentioned Visual Studio's Immediate Window feature as an example what of he wanted to achieve ("Just doing a simple ? objectname will give me a nicely formatted 'dump' of the object"). ? objectname prints out all the fields as well. This has been immensely helpful - one of my most used extension methods to date - I'm not questioning that it's useful, only that it dumps entire objects.
          – Konrad Morawski
          Sep 20 '12 at 8:24






          He didn't say fields - he said entire objects, which includes fields. He also mentioned Visual Studio's Immediate Window feature as an example what of he wanted to achieve ("Just doing a simple ? objectname will give me a nicely formatted 'dump' of the object"). ? objectname prints out all the fields as well. This has been immensely helpful - one of my most used extension methods to date - I'm not questioning that it's useful, only that it dumps entire objects.
          – Konrad Morawski
          Sep 20 '12 at 8:24






          2




          2




          @KonradMorawski Wrong entire objects means a recursive dump of the object, NOT that it includes fields, which can easily lead to infinite recursive loop. You shouldn't assume what others are implying. My answer is both relevant and helpful, your down vote + comment is not.
          – mythz
          Sep 20 '12 at 9:08






          @KonradMorawski Wrong entire objects means a recursive dump of the object, NOT that it includes fields, which can easily lead to infinite recursive loop. You shouldn't assume what others are implying. My answer is both relevant and helpful, your down vote + comment is not.
          – mythz
          Sep 20 '12 at 9:08






          1




          1




          @mythz yes of course you need to prevent a stack overflow (eg. every Int32 field has a MaxValue field, which is an Int32 itself...), that's a good point, but it doesn't change the fact that objects - and certainly entire ones - consist of fields, too, not just properties. What's more (you did not address that one), ? objectname in the Immediate Window does display fields - without triggering an infinite loop. If that's about my downvote, I can withdraw it (if you let me by unlocking it, that is). I disagree in principle anyway.
          – Konrad Morawski
          Sep 20 '12 at 9:33




          @mythz yes of course you need to prevent a stack overflow (eg. every Int32 field has a MaxValue field, which is an Int32 itself...), that's a good point, but it doesn't change the fact that objects - and certainly entire ones - consist of fields, too, not just properties. What's more (you did not address that one), ? objectname in the Immediate Window does display fields - without triggering an infinite loop. If that's about my downvote, I can withdraw it (if you let me by unlocking it, that is). I disagree in principle anyway.
          – Konrad Morawski
          Sep 20 '12 at 9:33




          2




          2




          -1 for essentially a link-only answer, though it looks great if I could use it! Perhaps I'm blind, but I can't find source via that link; the two upload folders are empty. Is the code too long to include in the answer?
          – user565869
          Jul 14 '14 at 19:26




          -1 for essentially a link-only answer, though it looks great if I could use it! Perhaps I'm blind, but I can't find source via that link; the two upload folders are empty. Is the code too long to include in the answer?
          – user565869
          Jul 14 '14 at 19:26










          up vote
          14
          down vote













          You could use Visual Studio Immediate Window



          Just paste this (change actual to your object name obviously):



          Newtonsoft.Json.JsonConvert.SerializeObject(actual);


          It should print object in JSON
          enter image description here



          You should be able to copy it over textmechanic text tool or notepad++ and replace escaped quotes (") with " and newlines (rn) with empty space, then remove double quotes (") from beginning and end and paste it to jsbeautifier to make it more readable.



          UPDATE to OP's comment



          public static class Dumper
          {
          public static void Dump(this object obj)
          {
          Console.WriteLine(Newtonsoft.Json.JsonConvert.SerializeObject(obj)); // your logger
          }
          }


          this should allow you to dump any object.



          Hope this saves you some time.






          share|improve this answer























          • Thanks. Perhaps you didn't catch it in my original question, but I indicated that I already knew about the immediate window, and I wanted to do the same thing when logging in my app.
            – Dan Esparza
            Jun 23 '15 at 15:38










          • @DanEsparza Console.Log(Newtonsoft.Json.JsonConvert.SerializeObject(actual)); ? :) and yes I indeed missed it. This question comes up when you search google.co.uk/…
            – Matas Vaitkevicius
            Jun 23 '15 at 15:52








          • 1




            FYI, when you have a JSON string in a C# string, click on the spyglass icon to the right of the string and pick the Text Visualizer. It will bring up a window that shows a plain text version of the JSON string (not escaped quotes or rn).
            – Walter
            Aug 31 '16 at 1:00















          up vote
          14
          down vote













          You could use Visual Studio Immediate Window



          Just paste this (change actual to your object name obviously):



          Newtonsoft.Json.JsonConvert.SerializeObject(actual);


          It should print object in JSON
          enter image description here



          You should be able to copy it over textmechanic text tool or notepad++ and replace escaped quotes (") with " and newlines (rn) with empty space, then remove double quotes (") from beginning and end and paste it to jsbeautifier to make it more readable.



          UPDATE to OP's comment



          public static class Dumper
          {
          public static void Dump(this object obj)
          {
          Console.WriteLine(Newtonsoft.Json.JsonConvert.SerializeObject(obj)); // your logger
          }
          }


          this should allow you to dump any object.



          Hope this saves you some time.






          share|improve this answer























          • Thanks. Perhaps you didn't catch it in my original question, but I indicated that I already knew about the immediate window, and I wanted to do the same thing when logging in my app.
            – Dan Esparza
            Jun 23 '15 at 15:38










          • @DanEsparza Console.Log(Newtonsoft.Json.JsonConvert.SerializeObject(actual)); ? :) and yes I indeed missed it. This question comes up when you search google.co.uk/…
            – Matas Vaitkevicius
            Jun 23 '15 at 15:52








          • 1




            FYI, when you have a JSON string in a C# string, click on the spyglass icon to the right of the string and pick the Text Visualizer. It will bring up a window that shows a plain text version of the JSON string (not escaped quotes or rn).
            – Walter
            Aug 31 '16 at 1:00













          up vote
          14
          down vote










          up vote
          14
          down vote









          You could use Visual Studio Immediate Window



          Just paste this (change actual to your object name obviously):



          Newtonsoft.Json.JsonConvert.SerializeObject(actual);


          It should print object in JSON
          enter image description here



          You should be able to copy it over textmechanic text tool or notepad++ and replace escaped quotes (") with " and newlines (rn) with empty space, then remove double quotes (") from beginning and end and paste it to jsbeautifier to make it more readable.



          UPDATE to OP's comment



          public static class Dumper
          {
          public static void Dump(this object obj)
          {
          Console.WriteLine(Newtonsoft.Json.JsonConvert.SerializeObject(obj)); // your logger
          }
          }


          this should allow you to dump any object.



          Hope this saves you some time.






          share|improve this answer














          You could use Visual Studio Immediate Window



          Just paste this (change actual to your object name obviously):



          Newtonsoft.Json.JsonConvert.SerializeObject(actual);


          It should print object in JSON
          enter image description here



          You should be able to copy it over textmechanic text tool or notepad++ and replace escaped quotes (") with " and newlines (rn) with empty space, then remove double quotes (") from beginning and end and paste it to jsbeautifier to make it more readable.



          UPDATE to OP's comment



          public static class Dumper
          {
          public static void Dump(this object obj)
          {
          Console.WriteLine(Newtonsoft.Json.JsonConvert.SerializeObject(obj)); // your logger
          }
          }


          this should allow you to dump any object.



          Hope this saves you some time.







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Jun 23 '15 at 16:05

























          answered Jun 23 '15 at 10:01









          Matas Vaitkevicius

          32.3k15161171




          32.3k15161171












          • Thanks. Perhaps you didn't catch it in my original question, but I indicated that I already knew about the immediate window, and I wanted to do the same thing when logging in my app.
            – Dan Esparza
            Jun 23 '15 at 15:38










          • @DanEsparza Console.Log(Newtonsoft.Json.JsonConvert.SerializeObject(actual)); ? :) and yes I indeed missed it. This question comes up when you search google.co.uk/…
            – Matas Vaitkevicius
            Jun 23 '15 at 15:52








          • 1




            FYI, when you have a JSON string in a C# string, click on the spyglass icon to the right of the string and pick the Text Visualizer. It will bring up a window that shows a plain text version of the JSON string (not escaped quotes or rn).
            – Walter
            Aug 31 '16 at 1:00


















          • Thanks. Perhaps you didn't catch it in my original question, but I indicated that I already knew about the immediate window, and I wanted to do the same thing when logging in my app.
            – Dan Esparza
            Jun 23 '15 at 15:38










          • @DanEsparza Console.Log(Newtonsoft.Json.JsonConvert.SerializeObject(actual)); ? :) and yes I indeed missed it. This question comes up when you search google.co.uk/…
            – Matas Vaitkevicius
            Jun 23 '15 at 15:52








          • 1




            FYI, when you have a JSON string in a C# string, click on the spyglass icon to the right of the string and pick the Text Visualizer. It will bring up a window that shows a plain text version of the JSON string (not escaped quotes or rn).
            – Walter
            Aug 31 '16 at 1:00
















          Thanks. Perhaps you didn't catch it in my original question, but I indicated that I already knew about the immediate window, and I wanted to do the same thing when logging in my app.
          – Dan Esparza
          Jun 23 '15 at 15:38




          Thanks. Perhaps you didn't catch it in my original question, but I indicated that I already knew about the immediate window, and I wanted to do the same thing when logging in my app.
          – Dan Esparza
          Jun 23 '15 at 15:38












          @DanEsparza Console.Log(Newtonsoft.Json.JsonConvert.SerializeObject(actual)); ? :) and yes I indeed missed it. This question comes up when you search google.co.uk/…
          – Matas Vaitkevicius
          Jun 23 '15 at 15:52






          @DanEsparza Console.Log(Newtonsoft.Json.JsonConvert.SerializeObject(actual)); ? :) and yes I indeed missed it. This question comes up when you search google.co.uk/…
          – Matas Vaitkevicius
          Jun 23 '15 at 15:52






          1




          1




          FYI, when you have a JSON string in a C# string, click on the spyglass icon to the right of the string and pick the Text Visualizer. It will bring up a window that shows a plain text version of the JSON string (not escaped quotes or rn).
          – Walter
          Aug 31 '16 at 1:00




          FYI, when you have a JSON string in a C# string, click on the spyglass icon to the right of the string and pick the Text Visualizer. It will bring up a window that shows a plain text version of the JSON string (not escaped quotes or rn).
          – Walter
          Aug 31 '16 at 1:00










          up vote
          10
          down vote













          Here is a stupidly simple way to write a flat object, nicely formatted:



          using Newtonsoft.Json.Linq;

          Debug.WriteLine("The object is " + JObject.FromObject(theObjectToDump).ToString());


          What's going on is that the object is first converted to a JSON internal representation by JObject.FromObject, and then converted to JSON string by ToString. (And of course a JSON string is a very nice representation of a simple object, especially since ToString will include newlines and indents.) The "ToString" is of course extraneous (as it's implied by using + to concat a string and an object), but I kinda like to specify it here.






          share|improve this answer

















          • 3




            JsonConvert.SerializeObject(apprec,Formatting.Indented) for comfortable reading in log
            – Tertium
            Aug 23 '16 at 23:04

















          up vote
          10
          down vote













          Here is a stupidly simple way to write a flat object, nicely formatted:



          using Newtonsoft.Json.Linq;

          Debug.WriteLine("The object is " + JObject.FromObject(theObjectToDump).ToString());


          What's going on is that the object is first converted to a JSON internal representation by JObject.FromObject, and then converted to JSON string by ToString. (And of course a JSON string is a very nice representation of a simple object, especially since ToString will include newlines and indents.) The "ToString" is of course extraneous (as it's implied by using + to concat a string and an object), but I kinda like to specify it here.






          share|improve this answer

















          • 3




            JsonConvert.SerializeObject(apprec,Formatting.Indented) for comfortable reading in log
            – Tertium
            Aug 23 '16 at 23:04















          up vote
          10
          down vote










          up vote
          10
          down vote









          Here is a stupidly simple way to write a flat object, nicely formatted:



          using Newtonsoft.Json.Linq;

          Debug.WriteLine("The object is " + JObject.FromObject(theObjectToDump).ToString());


          What's going on is that the object is first converted to a JSON internal representation by JObject.FromObject, and then converted to JSON string by ToString. (And of course a JSON string is a very nice representation of a simple object, especially since ToString will include newlines and indents.) The "ToString" is of course extraneous (as it's implied by using + to concat a string and an object), but I kinda like to specify it here.






          share|improve this answer












          Here is a stupidly simple way to write a flat object, nicely formatted:



          using Newtonsoft.Json.Linq;

          Debug.WriteLine("The object is " + JObject.FromObject(theObjectToDump).ToString());


          What's going on is that the object is first converted to a JSON internal representation by JObject.FromObject, and then converted to JSON string by ToString. (And of course a JSON string is a very nice representation of a simple object, especially since ToString will include newlines and indents.) The "ToString" is of course extraneous (as it's implied by using + to concat a string and an object), but I kinda like to specify it here.







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Jun 10 '14 at 21:08









          Hot Licks

          37.7k1577133




          37.7k1577133








          • 3




            JsonConvert.SerializeObject(apprec,Formatting.Indented) for comfortable reading in log
            – Tertium
            Aug 23 '16 at 23:04
















          • 3




            JsonConvert.SerializeObject(apprec,Formatting.Indented) for comfortable reading in log
            – Tertium
            Aug 23 '16 at 23:04










          3




          3




          JsonConvert.SerializeObject(apprec,Formatting.Indented) for comfortable reading in log
          – Tertium
          Aug 23 '16 at 23:04






          JsonConvert.SerializeObject(apprec,Formatting.Indented) for comfortable reading in log
          – Tertium
          Aug 23 '16 at 23:04












          up vote
          4
          down vote













          You could use reflection and loop through all the object properties, then get their values and save them to the log. The formatting is really trivial (you could use t to indent an objects properties and its values):



          MyObject
          Property1 = value
          Property2 = value2
          OtherObject
          OtherProperty = value ...





          share|improve this answer

























            up vote
            4
            down vote













            You could use reflection and loop through all the object properties, then get their values and save them to the log. The formatting is really trivial (you could use t to indent an objects properties and its values):



            MyObject
            Property1 = value
            Property2 = value2
            OtherObject
            OtherProperty = value ...





            share|improve this answer























              up vote
              4
              down vote










              up vote
              4
              down vote









              You could use reflection and loop through all the object properties, then get their values and save them to the log. The formatting is really trivial (you could use t to indent an objects properties and its values):



              MyObject
              Property1 = value
              Property2 = value2
              OtherObject
              OtherProperty = value ...





              share|improve this answer












              You could use reflection and loop through all the object properties, then get their values and save them to the log. The formatting is really trivial (you could use t to indent an objects properties and its values):



              MyObject
              Property1 = value
              Property2 = value2
              OtherObject
              OtherProperty = value ...






              share|improve this answer












              share|improve this answer



              share|improve this answer










              answered Dec 11 '08 at 18:05









              Ricardo Villamil

              4,36812625




              4,36812625






















                  up vote
                  3
                  down vote













                  What I like doing is overriding ToString() so that I get more useful output beyond the type name. This is handy in the debugger, you can see the information you want about an object without needing to expand it.






                  share|improve this answer

























                    up vote
                    3
                    down vote













                    What I like doing is overriding ToString() so that I get more useful output beyond the type name. This is handy in the debugger, you can see the information you want about an object without needing to expand it.






                    share|improve this answer























                      up vote
                      3
                      down vote










                      up vote
                      3
                      down vote









                      What I like doing is overriding ToString() so that I get more useful output beyond the type name. This is handy in the debugger, you can see the information you want about an object without needing to expand it.






                      share|improve this answer












                      What I like doing is overriding ToString() so that I get more useful output beyond the type name. This is handy in the debugger, you can see the information you want about an object without needing to expand it.







                      share|improve this answer












                      share|improve this answer



                      share|improve this answer










                      answered Dec 11 '08 at 19:05









                      Darryl Braaten

                      4,28433145




                      4,28433145






















                          up vote
                          3
                          down vote













                          I found a library called ObjectPrinter which allows to easily dump objects and collections to strings (and more). It does exactly what I needed.






                          share|improve this answer

























                            up vote
                            3
                            down vote













                            I found a library called ObjectPrinter which allows to easily dump objects and collections to strings (and more). It does exactly what I needed.






                            share|improve this answer























                              up vote
                              3
                              down vote










                              up vote
                              3
                              down vote









                              I found a library called ObjectPrinter which allows to easily dump objects and collections to strings (and more). It does exactly what I needed.






                              share|improve this answer












                              I found a library called ObjectPrinter which allows to easily dump objects and collections to strings (and more). It does exactly what I needed.







                              share|improve this answer












                              share|improve this answer



                              share|improve this answer










                              answered Aug 25 '15 at 12:06









                              Marek Dzikiewicz

                              2,53011619




                              2,53011619






















                                  up vote
                                  3
                                  down vote













                                  Following is another version that does the same thing (and handle nested properties), which I think is simpler (no dependencies on external libraries and can be modified easily to do things other than logging):



                                  public class ObjectDumper
                                  {
                                  public static string Dump(object obj)
                                  {
                                  return new ObjectDumper().DumpObject(obj);
                                  }

                                  StringBuilder _dumpBuilder = new StringBuilder();

                                  string DumpObject(object obj)
                                  {
                                  DumpObject(obj, 0);
                                  return _dumpBuilder.ToString();
                                  }

                                  void DumpObject(object obj, int nestingLevel = 0)
                                  {
                                  var nestingSpaces = "".PadLeft(nestingLevel * 4);

                                  if (obj == null)
                                  {
                                  _dumpBuilder.AppendFormat("{0}nulln", nestingSpaces);
                                  }
                                  else if (obj is string || obj.GetType().IsPrimitive)
                                  {
                                  _dumpBuilder.AppendFormat("{0}{1}n", nestingSpaces, obj);
                                  }
                                  else if (ImplementsDictionary(obj.GetType()))
                                  {
                                  using (var e = ((dynamic)obj).GetEnumerator())
                                  {
                                  var enumerator = (IEnumerator)e;
                                  while (enumerator.MoveNext())
                                  {
                                  dynamic p = enumerator.Current;

                                  var key = p.Key;
                                  var value = p.Value;
                                  _dumpBuilder.AppendFormat("{0}{1} ({2})n", nestingSpaces, key, value != null ? value.GetType().ToString() : "<null>");
                                  DumpObject(value, nestingLevel + 1);
                                  }
                                  }
                                  }
                                  else if (obj is IEnumerable)
                                  {
                                  foreach (dynamic p in obj as IEnumerable)
                                  {
                                  DumpObject(p, nestingLevel);
                                  }
                                  }
                                  else
                                  {
                                  foreach (PropertyDescriptor descriptor in TypeDescriptor.GetProperties(obj))
                                  {
                                  string name = descriptor.Name;
                                  object value = descriptor.GetValue(obj);

                                  _dumpBuilder.AppendFormat("{0}{1} ({2})n", nestingSpaces, name, value != null ? value.GetType().ToString() : "<null>");
                                  DumpObject(value, nestingLevel + 1);
                                  }
                                  }
                                  }

                                  bool ImplementsDictionary(Type t)
                                  {
                                  return t.GetInterfaces().Any(i => i.Name.Contains("IDictionary"));
                                  }
                                  }







                                  share|improve this answer



















                                  • 1




                                    this will die horribly if you have a Date property in your inner object ... just saying ...
                                    – Noctis
                                    Sep 7 '17 at 4:43















                                  up vote
                                  3
                                  down vote













                                  Following is another version that does the same thing (and handle nested properties), which I think is simpler (no dependencies on external libraries and can be modified easily to do things other than logging):



                                  public class ObjectDumper
                                  {
                                  public static string Dump(object obj)
                                  {
                                  return new ObjectDumper().DumpObject(obj);
                                  }

                                  StringBuilder _dumpBuilder = new StringBuilder();

                                  string DumpObject(object obj)
                                  {
                                  DumpObject(obj, 0);
                                  return _dumpBuilder.ToString();
                                  }

                                  void DumpObject(object obj, int nestingLevel = 0)
                                  {
                                  var nestingSpaces = "".PadLeft(nestingLevel * 4);

                                  if (obj == null)
                                  {
                                  _dumpBuilder.AppendFormat("{0}nulln", nestingSpaces);
                                  }
                                  else if (obj is string || obj.GetType().IsPrimitive)
                                  {
                                  _dumpBuilder.AppendFormat("{0}{1}n", nestingSpaces, obj);
                                  }
                                  else if (ImplementsDictionary(obj.GetType()))
                                  {
                                  using (var e = ((dynamic)obj).GetEnumerator())
                                  {
                                  var enumerator = (IEnumerator)e;
                                  while (enumerator.MoveNext())
                                  {
                                  dynamic p = enumerator.Current;

                                  var key = p.Key;
                                  var value = p.Value;
                                  _dumpBuilder.AppendFormat("{0}{1} ({2})n", nestingSpaces, key, value != null ? value.GetType().ToString() : "<null>");
                                  DumpObject(value, nestingLevel + 1);
                                  }
                                  }
                                  }
                                  else if (obj is IEnumerable)
                                  {
                                  foreach (dynamic p in obj as IEnumerable)
                                  {
                                  DumpObject(p, nestingLevel);
                                  }
                                  }
                                  else
                                  {
                                  foreach (PropertyDescriptor descriptor in TypeDescriptor.GetProperties(obj))
                                  {
                                  string name = descriptor.Name;
                                  object value = descriptor.GetValue(obj);

                                  _dumpBuilder.AppendFormat("{0}{1} ({2})n", nestingSpaces, name, value != null ? value.GetType().ToString() : "<null>");
                                  DumpObject(value, nestingLevel + 1);
                                  }
                                  }
                                  }

                                  bool ImplementsDictionary(Type t)
                                  {
                                  return t.GetInterfaces().Any(i => i.Name.Contains("IDictionary"));
                                  }
                                  }







                                  share|improve this answer



















                                  • 1




                                    this will die horribly if you have a Date property in your inner object ... just saying ...
                                    – Noctis
                                    Sep 7 '17 at 4:43













                                  up vote
                                  3
                                  down vote










                                  up vote
                                  3
                                  down vote









                                  Following is another version that does the same thing (and handle nested properties), which I think is simpler (no dependencies on external libraries and can be modified easily to do things other than logging):



                                  public class ObjectDumper
                                  {
                                  public static string Dump(object obj)
                                  {
                                  return new ObjectDumper().DumpObject(obj);
                                  }

                                  StringBuilder _dumpBuilder = new StringBuilder();

                                  string DumpObject(object obj)
                                  {
                                  DumpObject(obj, 0);
                                  return _dumpBuilder.ToString();
                                  }

                                  void DumpObject(object obj, int nestingLevel = 0)
                                  {
                                  var nestingSpaces = "".PadLeft(nestingLevel * 4);

                                  if (obj == null)
                                  {
                                  _dumpBuilder.AppendFormat("{0}nulln", nestingSpaces);
                                  }
                                  else if (obj is string || obj.GetType().IsPrimitive)
                                  {
                                  _dumpBuilder.AppendFormat("{0}{1}n", nestingSpaces, obj);
                                  }
                                  else if (ImplementsDictionary(obj.GetType()))
                                  {
                                  using (var e = ((dynamic)obj).GetEnumerator())
                                  {
                                  var enumerator = (IEnumerator)e;
                                  while (enumerator.MoveNext())
                                  {
                                  dynamic p = enumerator.Current;

                                  var key = p.Key;
                                  var value = p.Value;
                                  _dumpBuilder.AppendFormat("{0}{1} ({2})n", nestingSpaces, key, value != null ? value.GetType().ToString() : "<null>");
                                  DumpObject(value, nestingLevel + 1);
                                  }
                                  }
                                  }
                                  else if (obj is IEnumerable)
                                  {
                                  foreach (dynamic p in obj as IEnumerable)
                                  {
                                  DumpObject(p, nestingLevel);
                                  }
                                  }
                                  else
                                  {
                                  foreach (PropertyDescriptor descriptor in TypeDescriptor.GetProperties(obj))
                                  {
                                  string name = descriptor.Name;
                                  object value = descriptor.GetValue(obj);

                                  _dumpBuilder.AppendFormat("{0}{1} ({2})n", nestingSpaces, name, value != null ? value.GetType().ToString() : "<null>");
                                  DumpObject(value, nestingLevel + 1);
                                  }
                                  }
                                  }

                                  bool ImplementsDictionary(Type t)
                                  {
                                  return t.GetInterfaces().Any(i => i.Name.Contains("IDictionary"));
                                  }
                                  }







                                  share|improve this answer














                                  Following is another version that does the same thing (and handle nested properties), which I think is simpler (no dependencies on external libraries and can be modified easily to do things other than logging):



                                  public class ObjectDumper
                                  {
                                  public static string Dump(object obj)
                                  {
                                  return new ObjectDumper().DumpObject(obj);
                                  }

                                  StringBuilder _dumpBuilder = new StringBuilder();

                                  string DumpObject(object obj)
                                  {
                                  DumpObject(obj, 0);
                                  return _dumpBuilder.ToString();
                                  }

                                  void DumpObject(object obj, int nestingLevel = 0)
                                  {
                                  var nestingSpaces = "".PadLeft(nestingLevel * 4);

                                  if (obj == null)
                                  {
                                  _dumpBuilder.AppendFormat("{0}nulln", nestingSpaces);
                                  }
                                  else if (obj is string || obj.GetType().IsPrimitive)
                                  {
                                  _dumpBuilder.AppendFormat("{0}{1}n", nestingSpaces, obj);
                                  }
                                  else if (ImplementsDictionary(obj.GetType()))
                                  {
                                  using (var e = ((dynamic)obj).GetEnumerator())
                                  {
                                  var enumerator = (IEnumerator)e;
                                  while (enumerator.MoveNext())
                                  {
                                  dynamic p = enumerator.Current;

                                  var key = p.Key;
                                  var value = p.Value;
                                  _dumpBuilder.AppendFormat("{0}{1} ({2})n", nestingSpaces, key, value != null ? value.GetType().ToString() : "<null>");
                                  DumpObject(value, nestingLevel + 1);
                                  }
                                  }
                                  }
                                  else if (obj is IEnumerable)
                                  {
                                  foreach (dynamic p in obj as IEnumerable)
                                  {
                                  DumpObject(p, nestingLevel);
                                  }
                                  }
                                  else
                                  {
                                  foreach (PropertyDescriptor descriptor in TypeDescriptor.GetProperties(obj))
                                  {
                                  string name = descriptor.Name;
                                  object value = descriptor.GetValue(obj);

                                  _dumpBuilder.AppendFormat("{0}{1} ({2})n", nestingSpaces, name, value != null ? value.GetType().ToString() : "<null>");
                                  DumpObject(value, nestingLevel + 1);
                                  }
                                  }
                                  }

                                  bool ImplementsDictionary(Type t)
                                  {
                                  return t.GetInterfaces().Any(i => i.Name.Contains("IDictionary"));
                                  }
                                  }








                                  share|improve this answer














                                  share|improve this answer



                                  share|improve this answer








                                  edited Feb 21 '17 at 2:40

























                                  answered Feb 16 '17 at 3:02









                                  engineforce

                                  1,1591112




                                  1,1591112








                                  • 1




                                    this will die horribly if you have a Date property in your inner object ... just saying ...
                                    – Noctis
                                    Sep 7 '17 at 4:43














                                  • 1




                                    this will die horribly if you have a Date property in your inner object ... just saying ...
                                    – Noctis
                                    Sep 7 '17 at 4:43








                                  1




                                  1




                                  this will die horribly if you have a Date property in your inner object ... just saying ...
                                  – Noctis
                                  Sep 7 '17 at 4:43




                                  this will die horribly if you have a Date property in your inner object ... just saying ...
                                  – Noctis
                                  Sep 7 '17 at 4:43










                                  up vote
                                  2
                                  down vote













                                  You can write your own WriteLine method-



                                  public static void WriteLine<T>(T obj)
                                  {
                                  var t = typeof(T);
                                  var props = t.GetProperties();
                                  StringBuilder sb = new StringBuilder();
                                  foreach (var item in props)
                                  {
                                  sb.Append($"{item.Name}:{item.GetValue(obj,null)}; ");
                                  }
                                  sb.AppendLine();
                                  Console.WriteLine(sb.ToString());
                                  }


                                  Use it like-



                                  WriteLine(myObject);


                                  To write a collection we can use-



                                   var ifaces = t.GetInterfaces();
                                  if (ifaces.Any(o => o.Name.StartsWith("ICollection")))
                                  {

                                  dynamic lst = t.GetMethod("GetEnumerator").Invoke(obj, null);
                                  while (lst.MoveNext())
                                  {
                                  WriteLine(lst.Current);
                                  }
                                  }


                                  The method may look like-



                                   public static void WriteLine<T>(T obj)
                                  {
                                  var t = typeof(T);
                                  var ifaces = t.GetInterfaces();
                                  if (ifaces.Any(o => o.Name.StartsWith("ICollection")))
                                  {

                                  dynamic lst = t.GetMethod("GetEnumerator").Invoke(obj, null);
                                  while (lst.MoveNext())
                                  {
                                  WriteLine(lst.Current);
                                  }
                                  }
                                  else if (t.GetProperties().Any())
                                  {
                                  var props = t.GetProperties();
                                  StringBuilder sb = new StringBuilder();
                                  foreach (var item in props)
                                  {
                                  sb.Append($"{item.Name}:{item.GetValue(obj, null)}; ");
                                  }
                                  sb.AppendLine();
                                  Console.WriteLine(sb.ToString());
                                  }
                                  }


                                  Using if, else if and checking interfaces, attributes, base type, etc. and recursion (as this is a recursive method) in this way we may achieve an object dumper, but it is tedious for sure. Using the object dumper from Microsoft's LINQ Sample would save your time.






                                  share|improve this answer























                                  • Out of curiousity: How does this handle arrays or lists? Or properties that reference parent objects?
                                    – Dan Esparza
                                    Mar 1 '16 at 14:50










                                  • @DanEsparza Thanks to show me the way to be more specific.
                                    – Ariful Islam
                                    Mar 2 '16 at 6:33















                                  up vote
                                  2
                                  down vote













                                  You can write your own WriteLine method-



                                  public static void WriteLine<T>(T obj)
                                  {
                                  var t = typeof(T);
                                  var props = t.GetProperties();
                                  StringBuilder sb = new StringBuilder();
                                  foreach (var item in props)
                                  {
                                  sb.Append($"{item.Name}:{item.GetValue(obj,null)}; ");
                                  }
                                  sb.AppendLine();
                                  Console.WriteLine(sb.ToString());
                                  }


                                  Use it like-



                                  WriteLine(myObject);


                                  To write a collection we can use-



                                   var ifaces = t.GetInterfaces();
                                  if (ifaces.Any(o => o.Name.StartsWith("ICollection")))
                                  {

                                  dynamic lst = t.GetMethod("GetEnumerator").Invoke(obj, null);
                                  while (lst.MoveNext())
                                  {
                                  WriteLine(lst.Current);
                                  }
                                  }


                                  The method may look like-



                                   public static void WriteLine<T>(T obj)
                                  {
                                  var t = typeof(T);
                                  var ifaces = t.GetInterfaces();
                                  if (ifaces.Any(o => o.Name.StartsWith("ICollection")))
                                  {

                                  dynamic lst = t.GetMethod("GetEnumerator").Invoke(obj, null);
                                  while (lst.MoveNext())
                                  {
                                  WriteLine(lst.Current);
                                  }
                                  }
                                  else if (t.GetProperties().Any())
                                  {
                                  var props = t.GetProperties();
                                  StringBuilder sb = new StringBuilder();
                                  foreach (var item in props)
                                  {
                                  sb.Append($"{item.Name}:{item.GetValue(obj, null)}; ");
                                  }
                                  sb.AppendLine();
                                  Console.WriteLine(sb.ToString());
                                  }
                                  }


                                  Using if, else if and checking interfaces, attributes, base type, etc. and recursion (as this is a recursive method) in this way we may achieve an object dumper, but it is tedious for sure. Using the object dumper from Microsoft's LINQ Sample would save your time.






                                  share|improve this answer























                                  • Out of curiousity: How does this handle arrays or lists? Or properties that reference parent objects?
                                    – Dan Esparza
                                    Mar 1 '16 at 14:50










                                  • @DanEsparza Thanks to show me the way to be more specific.
                                    – Ariful Islam
                                    Mar 2 '16 at 6:33













                                  up vote
                                  2
                                  down vote










                                  up vote
                                  2
                                  down vote









                                  You can write your own WriteLine method-



                                  public static void WriteLine<T>(T obj)
                                  {
                                  var t = typeof(T);
                                  var props = t.GetProperties();
                                  StringBuilder sb = new StringBuilder();
                                  foreach (var item in props)
                                  {
                                  sb.Append($"{item.Name}:{item.GetValue(obj,null)}; ");
                                  }
                                  sb.AppendLine();
                                  Console.WriteLine(sb.ToString());
                                  }


                                  Use it like-



                                  WriteLine(myObject);


                                  To write a collection we can use-



                                   var ifaces = t.GetInterfaces();
                                  if (ifaces.Any(o => o.Name.StartsWith("ICollection")))
                                  {

                                  dynamic lst = t.GetMethod("GetEnumerator").Invoke(obj, null);
                                  while (lst.MoveNext())
                                  {
                                  WriteLine(lst.Current);
                                  }
                                  }


                                  The method may look like-



                                   public static void WriteLine<T>(T obj)
                                  {
                                  var t = typeof(T);
                                  var ifaces = t.GetInterfaces();
                                  if (ifaces.Any(o => o.Name.StartsWith("ICollection")))
                                  {

                                  dynamic lst = t.GetMethod("GetEnumerator").Invoke(obj, null);
                                  while (lst.MoveNext())
                                  {
                                  WriteLine(lst.Current);
                                  }
                                  }
                                  else if (t.GetProperties().Any())
                                  {
                                  var props = t.GetProperties();
                                  StringBuilder sb = new StringBuilder();
                                  foreach (var item in props)
                                  {
                                  sb.Append($"{item.Name}:{item.GetValue(obj, null)}; ");
                                  }
                                  sb.AppendLine();
                                  Console.WriteLine(sb.ToString());
                                  }
                                  }


                                  Using if, else if and checking interfaces, attributes, base type, etc. and recursion (as this is a recursive method) in this way we may achieve an object dumper, but it is tedious for sure. Using the object dumper from Microsoft's LINQ Sample would save your time.






                                  share|improve this answer














                                  You can write your own WriteLine method-



                                  public static void WriteLine<T>(T obj)
                                  {
                                  var t = typeof(T);
                                  var props = t.GetProperties();
                                  StringBuilder sb = new StringBuilder();
                                  foreach (var item in props)
                                  {
                                  sb.Append($"{item.Name}:{item.GetValue(obj,null)}; ");
                                  }
                                  sb.AppendLine();
                                  Console.WriteLine(sb.ToString());
                                  }


                                  Use it like-



                                  WriteLine(myObject);


                                  To write a collection we can use-



                                   var ifaces = t.GetInterfaces();
                                  if (ifaces.Any(o => o.Name.StartsWith("ICollection")))
                                  {

                                  dynamic lst = t.GetMethod("GetEnumerator").Invoke(obj, null);
                                  while (lst.MoveNext())
                                  {
                                  WriteLine(lst.Current);
                                  }
                                  }


                                  The method may look like-



                                   public static void WriteLine<T>(T obj)
                                  {
                                  var t = typeof(T);
                                  var ifaces = t.GetInterfaces();
                                  if (ifaces.Any(o => o.Name.StartsWith("ICollection")))
                                  {

                                  dynamic lst = t.GetMethod("GetEnumerator").Invoke(obj, null);
                                  while (lst.MoveNext())
                                  {
                                  WriteLine(lst.Current);
                                  }
                                  }
                                  else if (t.GetProperties().Any())
                                  {
                                  var props = t.GetProperties();
                                  StringBuilder sb = new StringBuilder();
                                  foreach (var item in props)
                                  {
                                  sb.Append($"{item.Name}:{item.GetValue(obj, null)}; ");
                                  }
                                  sb.AppendLine();
                                  Console.WriteLine(sb.ToString());
                                  }
                                  }


                                  Using if, else if and checking interfaces, attributes, base type, etc. and recursion (as this is a recursive method) in this way we may achieve an object dumper, but it is tedious for sure. Using the object dumper from Microsoft's LINQ Sample would save your time.







                                  share|improve this answer














                                  share|improve this answer



                                  share|improve this answer








                                  edited Mar 2 '16 at 6:28

























                                  answered Feb 26 '16 at 17:45









                                  Ariful Islam

                                  36737




                                  36737












                                  • Out of curiousity: How does this handle arrays or lists? Or properties that reference parent objects?
                                    – Dan Esparza
                                    Mar 1 '16 at 14:50










                                  • @DanEsparza Thanks to show me the way to be more specific.
                                    – Ariful Islam
                                    Mar 2 '16 at 6:33


















                                  • Out of curiousity: How does this handle arrays or lists? Or properties that reference parent objects?
                                    – Dan Esparza
                                    Mar 1 '16 at 14:50










                                  • @DanEsparza Thanks to show me the way to be more specific.
                                    – Ariful Islam
                                    Mar 2 '16 at 6:33
















                                  Out of curiousity: How does this handle arrays or lists? Or properties that reference parent objects?
                                  – Dan Esparza
                                  Mar 1 '16 at 14:50




                                  Out of curiousity: How does this handle arrays or lists? Or properties that reference parent objects?
                                  – Dan Esparza
                                  Mar 1 '16 at 14:50












                                  @DanEsparza Thanks to show me the way to be more specific.
                                  – Ariful Islam
                                  Mar 2 '16 at 6:33




                                  @DanEsparza Thanks to show me the way to be more specific.
                                  – Ariful Islam
                                  Mar 2 '16 at 6:33










                                  up vote
                                  0
                                  down vote













                                  Based on @engineforce answer, I made this class that I'm using in a PCL project of a Xamarin Solution:



                                  /// <summary>
                                  /// Based on: https://stackoverflow.com/a/42264037/6155481
                                  /// </summary>
                                  public class ObjectDumper
                                  {
                                  public static string Dump(object obj)
                                  {
                                  return new ObjectDumper().DumpObject(obj);
                                  }

                                  StringBuilder _dumpBuilder = new StringBuilder();

                                  string DumpObject(object obj)
                                  {
                                  DumpObject(obj, 0);
                                  return _dumpBuilder.ToString();
                                  }

                                  void DumpObject(object obj, int nestingLevel)
                                  {
                                  var nestingSpaces = "".PadLeft(nestingLevel * 4);

                                  if (obj == null)
                                  {
                                  _dumpBuilder.AppendFormat("{0}nulln", nestingSpaces);
                                  }
                                  else if (obj is string || obj.GetType().GetTypeInfo().IsPrimitive || obj.GetType().GetTypeInfo().IsEnum)
                                  {
                                  _dumpBuilder.AppendFormat("{0}{1}n", nestingSpaces, obj);
                                  }
                                  else if (ImplementsDictionary(obj.GetType()))
                                  {
                                  using (var e = ((dynamic)obj).GetEnumerator())
                                  {
                                  var enumerator = (IEnumerator)e;
                                  while (enumerator.MoveNext())
                                  {
                                  dynamic p = enumerator.Current;

                                  var key = p.Key;
                                  var value = p.Value;
                                  _dumpBuilder.AppendFormat("{0}{1} ({2})n", nestingSpaces, key, value != null ? value.GetType().ToString() : "<null>");
                                  DumpObject(value, nestingLevel + 1);
                                  }
                                  }
                                  }
                                  else if (obj is IEnumerable)
                                  {
                                  foreach (dynamic p in obj as IEnumerable)
                                  {
                                  DumpObject(p, nestingLevel);
                                  }
                                  }
                                  else
                                  {
                                  foreach (PropertyInfo descriptor in obj.GetType().GetRuntimeProperties())
                                  {
                                  string name = descriptor.Name;
                                  object value = descriptor.GetValue(obj);

                                  _dumpBuilder.AppendFormat("{0}{1} ({2})n", nestingSpaces, name, value != null ? value.GetType().ToString() : "<null>");

                                  // TODO: Prevent recursion due to circular reference
                                  if (name == "Self" && HasBaseType(obj.GetType(), "NSObject"))
                                  {
                                  // In ObjC I need to break the recursion when I find the Self property
                                  // otherwise it will be an infinite recursion
                                  Console.WriteLine($"Found Self! {obj.GetType()}");
                                  }
                                  else
                                  {
                                  DumpObject(value, nestingLevel + 1);
                                  }
                                  }
                                  }
                                  }

                                  bool HasBaseType(Type type, string baseTypeName)
                                  {
                                  if (type == null) return false;

                                  string typeName = type.Name;

                                  if (baseTypeName == typeName) return true;

                                  return HasBaseType(type.GetTypeInfo().BaseType, baseTypeName);
                                  }

                                  bool ImplementsDictionary(Type t)
                                  {
                                  return t is IDictionary;
                                  }
                                  }





                                  share|improve this answer

























                                    up vote
                                    0
                                    down vote













                                    Based on @engineforce answer, I made this class that I'm using in a PCL project of a Xamarin Solution:



                                    /// <summary>
                                    /// Based on: https://stackoverflow.com/a/42264037/6155481
                                    /// </summary>
                                    public class ObjectDumper
                                    {
                                    public static string Dump(object obj)
                                    {
                                    return new ObjectDumper().DumpObject(obj);
                                    }

                                    StringBuilder _dumpBuilder = new StringBuilder();

                                    string DumpObject(object obj)
                                    {
                                    DumpObject(obj, 0);
                                    return _dumpBuilder.ToString();
                                    }

                                    void DumpObject(object obj, int nestingLevel)
                                    {
                                    var nestingSpaces = "".PadLeft(nestingLevel * 4);

                                    if (obj == null)
                                    {
                                    _dumpBuilder.AppendFormat("{0}nulln", nestingSpaces);
                                    }
                                    else if (obj is string || obj.GetType().GetTypeInfo().IsPrimitive || obj.GetType().GetTypeInfo().IsEnum)
                                    {
                                    _dumpBuilder.AppendFormat("{0}{1}n", nestingSpaces, obj);
                                    }
                                    else if (ImplementsDictionary(obj.GetType()))
                                    {
                                    using (var e = ((dynamic)obj).GetEnumerator())
                                    {
                                    var enumerator = (IEnumerator)e;
                                    while (enumerator.MoveNext())
                                    {
                                    dynamic p = enumerator.Current;

                                    var key = p.Key;
                                    var value = p.Value;
                                    _dumpBuilder.AppendFormat("{0}{1} ({2})n", nestingSpaces, key, value != null ? value.GetType().ToString() : "<null>");
                                    DumpObject(value, nestingLevel + 1);
                                    }
                                    }
                                    }
                                    else if (obj is IEnumerable)
                                    {
                                    foreach (dynamic p in obj as IEnumerable)
                                    {
                                    DumpObject(p, nestingLevel);
                                    }
                                    }
                                    else
                                    {
                                    foreach (PropertyInfo descriptor in obj.GetType().GetRuntimeProperties())
                                    {
                                    string name = descriptor.Name;
                                    object value = descriptor.GetValue(obj);

                                    _dumpBuilder.AppendFormat("{0}{1} ({2})n", nestingSpaces, name, value != null ? value.GetType().ToString() : "<null>");

                                    // TODO: Prevent recursion due to circular reference
                                    if (name == "Self" && HasBaseType(obj.GetType(), "NSObject"))
                                    {
                                    // In ObjC I need to break the recursion when I find the Self property
                                    // otherwise it will be an infinite recursion
                                    Console.WriteLine($"Found Self! {obj.GetType()}");
                                    }
                                    else
                                    {
                                    DumpObject(value, nestingLevel + 1);
                                    }
                                    }
                                    }
                                    }

                                    bool HasBaseType(Type type, string baseTypeName)
                                    {
                                    if (type == null) return false;

                                    string typeName = type.Name;

                                    if (baseTypeName == typeName) return true;

                                    return HasBaseType(type.GetTypeInfo().BaseType, baseTypeName);
                                    }

                                    bool ImplementsDictionary(Type t)
                                    {
                                    return t is IDictionary;
                                    }
                                    }





                                    share|improve this answer























                                      up vote
                                      0
                                      down vote










                                      up vote
                                      0
                                      down vote









                                      Based on @engineforce answer, I made this class that I'm using in a PCL project of a Xamarin Solution:



                                      /// <summary>
                                      /// Based on: https://stackoverflow.com/a/42264037/6155481
                                      /// </summary>
                                      public class ObjectDumper
                                      {
                                      public static string Dump(object obj)
                                      {
                                      return new ObjectDumper().DumpObject(obj);
                                      }

                                      StringBuilder _dumpBuilder = new StringBuilder();

                                      string DumpObject(object obj)
                                      {
                                      DumpObject(obj, 0);
                                      return _dumpBuilder.ToString();
                                      }

                                      void DumpObject(object obj, int nestingLevel)
                                      {
                                      var nestingSpaces = "".PadLeft(nestingLevel * 4);

                                      if (obj == null)
                                      {
                                      _dumpBuilder.AppendFormat("{0}nulln", nestingSpaces);
                                      }
                                      else if (obj is string || obj.GetType().GetTypeInfo().IsPrimitive || obj.GetType().GetTypeInfo().IsEnum)
                                      {
                                      _dumpBuilder.AppendFormat("{0}{1}n", nestingSpaces, obj);
                                      }
                                      else if (ImplementsDictionary(obj.GetType()))
                                      {
                                      using (var e = ((dynamic)obj).GetEnumerator())
                                      {
                                      var enumerator = (IEnumerator)e;
                                      while (enumerator.MoveNext())
                                      {
                                      dynamic p = enumerator.Current;

                                      var key = p.Key;
                                      var value = p.Value;
                                      _dumpBuilder.AppendFormat("{0}{1} ({2})n", nestingSpaces, key, value != null ? value.GetType().ToString() : "<null>");
                                      DumpObject(value, nestingLevel + 1);
                                      }
                                      }
                                      }
                                      else if (obj is IEnumerable)
                                      {
                                      foreach (dynamic p in obj as IEnumerable)
                                      {
                                      DumpObject(p, nestingLevel);
                                      }
                                      }
                                      else
                                      {
                                      foreach (PropertyInfo descriptor in obj.GetType().GetRuntimeProperties())
                                      {
                                      string name = descriptor.Name;
                                      object value = descriptor.GetValue(obj);

                                      _dumpBuilder.AppendFormat("{0}{1} ({2})n", nestingSpaces, name, value != null ? value.GetType().ToString() : "<null>");

                                      // TODO: Prevent recursion due to circular reference
                                      if (name == "Self" && HasBaseType(obj.GetType(), "NSObject"))
                                      {
                                      // In ObjC I need to break the recursion when I find the Self property
                                      // otherwise it will be an infinite recursion
                                      Console.WriteLine($"Found Self! {obj.GetType()}");
                                      }
                                      else
                                      {
                                      DumpObject(value, nestingLevel + 1);
                                      }
                                      }
                                      }
                                      }

                                      bool HasBaseType(Type type, string baseTypeName)
                                      {
                                      if (type == null) return false;

                                      string typeName = type.Name;

                                      if (baseTypeName == typeName) return true;

                                      return HasBaseType(type.GetTypeInfo().BaseType, baseTypeName);
                                      }

                                      bool ImplementsDictionary(Type t)
                                      {
                                      return t is IDictionary;
                                      }
                                      }





                                      share|improve this answer












                                      Based on @engineforce answer, I made this class that I'm using in a PCL project of a Xamarin Solution:



                                      /// <summary>
                                      /// Based on: https://stackoverflow.com/a/42264037/6155481
                                      /// </summary>
                                      public class ObjectDumper
                                      {
                                      public static string Dump(object obj)
                                      {
                                      return new ObjectDumper().DumpObject(obj);
                                      }

                                      StringBuilder _dumpBuilder = new StringBuilder();

                                      string DumpObject(object obj)
                                      {
                                      DumpObject(obj, 0);
                                      return _dumpBuilder.ToString();
                                      }

                                      void DumpObject(object obj, int nestingLevel)
                                      {
                                      var nestingSpaces = "".PadLeft(nestingLevel * 4);

                                      if (obj == null)
                                      {
                                      _dumpBuilder.AppendFormat("{0}nulln", nestingSpaces);
                                      }
                                      else if (obj is string || obj.GetType().GetTypeInfo().IsPrimitive || obj.GetType().GetTypeInfo().IsEnum)
                                      {
                                      _dumpBuilder.AppendFormat("{0}{1}n", nestingSpaces, obj);
                                      }
                                      else if (ImplementsDictionary(obj.GetType()))
                                      {
                                      using (var e = ((dynamic)obj).GetEnumerator())
                                      {
                                      var enumerator = (IEnumerator)e;
                                      while (enumerator.MoveNext())
                                      {
                                      dynamic p = enumerator.Current;

                                      var key = p.Key;
                                      var value = p.Value;
                                      _dumpBuilder.AppendFormat("{0}{1} ({2})n", nestingSpaces, key, value != null ? value.GetType().ToString() : "<null>");
                                      DumpObject(value, nestingLevel + 1);
                                      }
                                      }
                                      }
                                      else if (obj is IEnumerable)
                                      {
                                      foreach (dynamic p in obj as IEnumerable)
                                      {
                                      DumpObject(p, nestingLevel);
                                      }
                                      }
                                      else
                                      {
                                      foreach (PropertyInfo descriptor in obj.GetType().GetRuntimeProperties())
                                      {
                                      string name = descriptor.Name;
                                      object value = descriptor.GetValue(obj);

                                      _dumpBuilder.AppendFormat("{0}{1} ({2})n", nestingSpaces, name, value != null ? value.GetType().ToString() : "<null>");

                                      // TODO: Prevent recursion due to circular reference
                                      if (name == "Self" && HasBaseType(obj.GetType(), "NSObject"))
                                      {
                                      // In ObjC I need to break the recursion when I find the Self property
                                      // otherwise it will be an infinite recursion
                                      Console.WriteLine($"Found Self! {obj.GetType()}");
                                      }
                                      else
                                      {
                                      DumpObject(value, nestingLevel + 1);
                                      }
                                      }
                                      }
                                      }

                                      bool HasBaseType(Type type, string baseTypeName)
                                      {
                                      if (type == null) return false;

                                      string typeName = type.Name;

                                      if (baseTypeName == typeName) return true;

                                      return HasBaseType(type.GetTypeInfo().BaseType, baseTypeName);
                                      }

                                      bool ImplementsDictionary(Type t)
                                      {
                                      return t is IDictionary;
                                      }
                                      }






                                      share|improve this answer












                                      share|improve this answer



                                      share|improve this answer










                                      answered Nov 11 at 22:09









                                      gianlucaparadise

                                      7518




                                      7518






























                                          draft saved

                                          draft discarded




















































                                          Thanks for contributing an answer to Stack Overflow!


                                          • Please be sure to answer the question. Provide details and share your research!

                                          But avoid



                                          • Asking for help, clarification, or responding to other answers.

                                          • Making statements based on opinion; back them up with references or personal experience.


                                          To learn more, see our tips on writing great answers.





                                          Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


                                          Please pay close attention to the following guidance:


                                          • Please be sure to answer the question. Provide details and share your research!

                                          But avoid



                                          • Asking for help, clarification, or responding to other answers.

                                          • Making statements based on opinion; back them up with references or personal experience.


                                          To learn more, see our tips on writing great answers.




                                          draft saved


                                          draft discarded














                                          StackExchange.ready(
                                          function () {
                                          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f360277%2fwhat-is-the-best-way-to-dump-entire-objects-to-a-log-in-c%23new-answer', 'question_page');
                                          }
                                          );

                                          Post as a guest















                                          Required, but never shown





















































                                          Required, but never shown














                                          Required, but never shown












                                          Required, but never shown







                                          Required, but never shown

































                                          Required, but never shown














                                          Required, but never shown












                                          Required, but never shown







                                          Required, but never shown







                                          Popular posts from this blog

                                          Florida Star v. B. J. F.

                                          Danny Elfman

                                          Lugert, Oklahoma