Why ToString() is mightier than the debugger…

My title today is a play on the phrase “The pen is mightier than the sword”. Those words were first written by novelist and playwright Edward Bulwer-Lytton in 1839, in his historical play Cardinal Richelieu (Who first said ‘The pen is mightier than the sword’?). While I hope that no one is going to plot to kill me after reading this post, I found my play on words amusing. My wife might tell me that I’m the only one but I digress. I know that this is basic stuff here so if you were expecting something more advanced you might want to skip this one. Sometimes it’s good to go back to basics.

In the programming world in which I live most programming languages, C# and Javascript, offer a method called ToString(). Usually this method will simply output the name of the objects type. I will demonstrate this here using LINQPad.

If you don’t have LINQPad yet, I would highly recommend downloading it as it is a wonderful tool. http://www.linqpad.net

Here is an example of a users class that will store our information. Things like the user identifier, the users name, and if they are an active user or not.

class User
{
    public int Id { get; set; }
    public string Name { get; set; }
    public bool Active { get; set; }
}

Seems simple enough. Let’s create an array of them and then filter out the active members only. This will give us a subset of the array we declared above.

var users = new [] { 
        new User { Id = 4, Name = "Fred", Active = true },
        new User { Id = 5, Name = "Wilma", Active = true },
        new User { Id = 6, Name = "Barny", Active = false },
        new User { Id = 47, Name = "Betty", Active = false },
    };
	
var activeUsers = users.Where(m => m.Active).ToArray();
//    Other work
activeUsers.Dump();

What does this look like in the debugger? I’m going to put a break point on line 10 so that we can look at this during runtime.
Active Users Before ToString() Override
Notice how I have to expand each element to see what the values of each property. This can be tedious especially when dealing with a large list of objects. As you can see in the example above I can see the value of the first item, “Fred”, but not the second item. Currently the debugger is obscuring the information from me. If my list was larger than it is, this would be a time consuming process to find the item that I was looking for.

We will simply override the ToString() method on the object and put something meaningful in the method.

class User
{
    public int Id { get; set; }
    public string Name { get; set; }
    public bool Active { get; set; }
	
    public override string ToString()
    {
        return 
        string.Format("User => Id: {0}, Name: {1}, Active: {2}", 
                                Id, Name, Active);
    }
}

Now you might be thinking, what good does that do? Well just by itself it doesn’t do anything. It just takes the property values and outputs them in a string. Well that’s just what the debugger does. Let’s take a look at the output of the same code in the debugger after making this change to our “User” class.
Active Users After ToString() Override
Viewing my list of active users just got easier. Now I can easily scan down through my list of users and see that “Fred” and “Wilma” are both there.

Where else can I use this other than the debugger? How about any of the System.Diagnostics classes such as Debugger or Trace. If I wanted to output to the contents of the class to a trace listener I could just put

Trace.WriteLine(user);

When the code is executed the ToString() method will be called on the object and Eureka! The customized string output is what will be seen in the trace message.

I presented this to a colleague who had never seen this before and later they claimed that it broke their class. Upon inspection of their code I found that what actually broke their class was the fact that they put logic in the method. They had a conditional in the method to display different things based on the values of the properties of the class. This was a mistake because they didn’t plan for one of them being null. So here is my official word of warning:

Don’t put logic in your ToString() method!

This should be very simple. Just output what you need to during debugging and don’t add complexity where it doesn’t belong. In fact, you should only output what you need to see in the debugger. If you have an object with 15 properties on it but you only need 3 of them to make a debugging decision only output those 3! So until next time, happy coding.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s