May 16

So, you know everything about text, right? – part XII

Posted in .NET Basics C#      Comments Off on So, you know everything about text, right? – part XII

Even though I’ve said that the previous post would wrap up this series, the truth is that there are still a couple of things I’d like to add in this text. Today, I’ll talk a little bit about the String.Format method which allows us to build strings from many formatted objects. Lets start with a simple example:

var str = String.Format( "{0} was born on the {1}",
                            new DateTime( 1976, 06, 27 ) );

The Format method receives a format string (1st parameter) which identifies replaceable parameters through numbered braces. You can use as many placeholders (defined by {position}) as you need. In our example, we’re using two placeholders: the first receives a string and the second is filled with a DateTime value. Printing the string str returns “Luis was born on the 27-06-1976 00:00:00”. If, like me, you’re running the previous code in a thread which is not using the “en-US” culture, you might find the previous result surprising (btw, if you do run it with the “en-US” culture, you end up getting “Luis was born on the 6/27/1976 12:00:00 AM”).

To understand why this happens, we have to take a look at the Format method internals. Internally, the Format method delegates the important work on the StringBuilder’s AppendFormat method, which ends up calling the ToString method for each of the placeholders values. By default, the ToString method will always format the object according to current culture applied to the thread (we’ll return to this topic in a future post). Notice that the ToString method is inherited by all types in the framework because it’s defined by the base Object class. However, its use is rather limited (ex.: it will always format the value according to the culture applied to the current thread). And that’s why the framework introduced the IFormattable interface. This interface, which is implemented by many types exposed by the framework, introduces a single method (also called ToString) which relies on a format provider (an instance of the IFormatProvider passed through the second parameter) for applying a specific format (passed through the first string) to the current object. This is a rather interesting topic and we’ll come back to it in the next post. For now, the important part is understanding that all the values that replace placeholders in a String.Format method call will have its ToString method called (and that ToString method can be the IFormattable’s ToString method, when the type implements that interface, or the “general” ToString method introduced by the base Object type).

Going back to the Format method, you should now that you can change the way formatting is applied to the placeholder values:

//customizing the way dates are presented
var str = String.Format( "{0} was born on the {1:dd/MM/yyyy}",
                            new DateTime( 1976, 06, 27 ) );

As you can see, the placeholder used for the DateTime parameter is a little more complex: besides indicating the position for the value which will be applied to that string, it also specifies the formatting that should be applied to that value (in this case, we’re using a custom string which formats the value on the form day/month/year). Whenever we use a placeholder on the form {position:format}, the method will try to call the IFormattable’s ToString method, passing it the format string. Currently, there are several format values which you can pass in the format position of a placeholder. For instance, if you’re interested in formatting numeric types, then this link will be of interest for  you (for getting a general reference on formatting, then check this article).

As you can see, the most important part of the work is done in the ToString method. Since we’ll be coming back to that in the next post, it’s time to wrap this post with a couple of important conclusions:

  • Whenever you need to format several objects into a string, then you should use the String.Format method. This is an efficient option since it relies on the StringBuilder’s AppendFormat method.
  • You can define the formatting of the value of a placeholder by using a placeholder on the form {position:format} (don’t forget that formatting is heavily influenced by the culture and the formatter – we’ll return to this topic in the next post).
  • Besides String.Format, there are other useful methods which rely on StringBuilder’s AppendFormat method. For instance, in console apps, there are overloads of Write and WriteLine methods which end up using a StringBuilder and its AppendFormat method for ensuring good performance in the formatting of several values.
  • Even though we didn’t show it, the truth is that there are overloads of the Format and AppendFormat methods which expect an instance of an IFormatProvider object (which is used for providing formatting information). When you pass an instance of this object, then all calls of the ToString method of the placeholder receive this instance.

And I guess that’s it for now. Stay tuned for more.