Thursday, April 20, 2006

ToString()

What should I do with ToString()?


In the Microsoft .Net Framework, ToString is defined in Object and is therefore ubiquitous (and everywhere too). You have the chance to override ToString whenever you want. But if you're thinking 'hmm... I don't override tostring() very much', then I would suggest maybe it's time to start. It certainly is handy to call whenever you need to output an error message. I almost just expect it to work (but nothing in life is free). Just call ToString() on your object and add to your trace messages. Very nice, but for the fact that error log messages aren't the only possible use for ToString(). Alas, with such a ubiquitous method, come multitudinous options for usage. Int.ToString() is an example of the obvious and straightforward, but what do you with an object with multiple properties and subobjects, and inheritences and so forth?


Proposed Behavior


I like the idea of ToString() displaying object identity. If you work with objects that model something real, like a business concept then output information that identifies the object. Not the internal key or database id, but the natural key. The data that people undestand to represent the essence of the thing. For instance, if your object represents a customer, ToString() would return the customer's name. Return a string that would be identifiable to a user using your software. Take a look at how DateTime.ToString() works, it is a good, simple model. The default ToString() returns the date as a string formatted according to the current thread culture. It displays the date in a way that I can read it. DateTime.ToString() takes the various members (day, month, year etc.) of DateTime and assembles them into a reasonably formatted presentation. Most objects have a 'name' property or a similar identifier. This is what ToString() should output. Converting an Address object with ToString() would probably output the address as it would be written on a letter.


Complex Objects


What about something like a Report object? Should ToString() return the report content as a properly formatted string? I would suggest that this kind of behavior is beyond the intent of ToString(). I would be inclined to only output details that again, identify the report, like its title, run date, and so on, not the content of the report. This should be left to specialized methods that can be expanded to more flexible use. Output a string that would would be written on a file folder tab. The content is in the folder, ToString is the human readable index. The information you would need use to retrieve the object.


Format Providers


Now it gets complicated (well, more complicated for me). What about customizing the output of ToString()? Back to my favorite, DateTime. People want to see dates in all sorts of different ways. DateTime.ToString() solves this by taking an optional IFormatProvider to display dates according to cultural preferences. Exposing ToString() with parameters is a good way to provide extra control over formatting. Again it still only outputs identity, just in a different format.


I am starting to implement the base ToString() on every class I write, and it is very convenient. I truly dislike seeing the Namespace.classname output when I call ToString(), very annoying in my view. Implement ToString and make users of your code happy (including yourself).

No comments:

Post a Comment