Overriding ToString()

Published Sun, Jul 31 2005 0:28 | William

I had mentioned reading Effective C#, 50 Specific Ways to Improve Your C#  back a few posts ago.  So I decided to show off a few of the techniques there as well as some new C# features and began with this post. .  Anyway, when I started writing out the examples, I kept adding new things and it started to turn into a really long piece.  Well, I need to start at the beginning and just let things go from there, otherwise I'll never get finished.  So let's start at the absolute beginning.  

I ran through a bunch of my existing code and looked for the number of times I did an  override on the ToString() method.  Except for a few times when I had a specific need to do so, I didn't find many. Well, if you look at the Framework, it's obvious that many of the classes have an override on the ToString() method and when they do, it's usually quite helpful.  I know, this is such an easy thing to do that it barely warrants discussion but I think that the fact that I (and the majority of developers I know as well as the majority of code I've seen) so seldom do it makes it worth emphasizing.  If you don't ever do it, it won't have ANY notable effect on the way your code runs.  However, it can (and does) make a difference in how user friendly your libraries are to developers using your code.  

Stated simply, you don't have to use XML Comments in your class libraries (and until recently, if you used VB.NET, you couldn't unless you wired them in yourself or bought an Add-In), you don't have to use enums to assist users with intellisense, you don't have to overload your constructors or other methods, but it sure makes your code a lot nicer to use if you do.  Well, if you look at the original Shocker Class I wrote, I have a override for ToString().  Assuming you passed in “Stink” and “Pink” respectively to the overloaded constructor, you'll see “One in the Stink, Two in the Pink” as the output.  However if you comment out the override, you'll DoubleI.TheShocker.Shocker.  Outside of the fact that this class was contrived and a bit flippant, the point should be obvious, namely, that you can provide a LOT more useful information than the Namespace.Class.

Outside of the Override though - you can overload the ToString() method and with a little footwork, have a much more user friendly class (the intellisense support alone is worth the price of admission)  Anyway, I know this is pretty lame but I'm trying to formulate as many things as I can with a simple example though.  By taking full advantage of the XML Comments you can do quite a bit and just a combination like this, of two really simple techniques can make your class a lot more user friendly.  And before you call me a l4mer for posting this - hold your horses, I'm going somewhere with this.:

/// <summary>

/// Method to provide a more granular feedback mechanism

/// for the user by specifying what is returned by the ToString()

/// method.

/// </summary>

/// <param name="formatOptions"><see cref="DoubleI.TheShocker.OutPutOptions"/> value

/// allowing the user to specify what they want to show.</param>

/// <returns><see cref="System.String"/> value showing the

/// <see cref="System.String"/> representation corresponding

/// to the <see cref="DoubleI.TheShocker.OutPutOptions"/> specified

/// by the user</returns>

/// <remarks>

/// Values for the <see cref="DoubleI.TheShocker.OutPutOptions"/>

/// parameter are specified below:

/// <list>

/// <item>OutPutOptions.None = 0</item>

/// <item>OutPutOptions.PrivateMembers = 1</item>

/// <item>OutPutOptions.ProtectedMembers = 2</item>

/// <item>OutPutOptions.PublicMembers = 3</item>

/// <item>OutPutOptions.All = 4</item>

/// <item>OutPutOptions.Silliness = 5</item>

/// </list>

/// </remarks>

/// <example>

/// Shocker ShockerSample = new Shocker("Stink", "Pink");

/// Console.WriteLine(ShockerSample.ToString(OutPutOptions.Silliness);

/// //Will yeild "One in the Stink, Two in the Pink

/// </example>

public String ToString(OutPutOptions formatOptions)

{

      switch (formatOptions)

      {

        case OutPutOptions.None:

             return "Nice Going A55Munch, this is a useless overload and call";

       case OutPutOptions.PrivateMembers:

           return String.Format("_oneValue: {0}, _twoValue {1}",

                                            this._oneValue,

                                            this._twoValue);

      case OutPutOptions.ProtectedMembers:

         return "Bill was lazy and didn't create any protected members yet";

     case OutPutOptions.PublicMembers:

       return String.Format("OneValue: {0}, TwoValue {1}",

                                       this.OneValue,

                                      this.TwoValue);

    case OutPutOptions.All:

       return String.Format("_oneValue: {0}, _twoValue {1}"

                                          + ", OneValue: {2}, TwoValue{3}",

                                       this._oneValue,

                                       this._twoValue,

                                       this.OneValue,

                                       this.TwoValue );

          case OutPutOptions.Silliness:

         default:

                return String.Format("One in the {0}, Two in the {1}",

                                    this.OneValue,

                                    this.TwoValue);

        }

  }

Comments

# TrackBack said on July 31, 2005 7:35 AM:

# William said on July 31, 2005 10:32 AM:

Good stuff. Thanks for logging it.

# TrackBack said on August 27, 2005 8:43 PM:

Overriding ToString()ooeess

Search

This Blog

Tags

Community

Archives

News

My other sites

Cool Stuff

Book Stuff

Security

ORM

Data Access

Funny Stuff

Compact Framework Stuff

Web Casts

My KnowledgeBase Articles

My MVP Profile

Design Patterns

Performance

Debugging

Remoting

My Fellow Authors

My Books

LINQ

Misc

Speech

Syndication

Email Notifications