Using String.format and Data Formatting in C#

Sometimes it’s the simple things we need to re-visit. Things like the humble little ‘string.format’ call that’s been with .NET right since the day it was first conceived. It’s also one of the least used things in the entire .NET library, where instead of something so simple, I consistently see people squabbling over which is better,  “String concatenation” or “String Builder”, which is faster, which is more flexible.

In this post I’m going to give ‘string.format’ some much needed love and show you that, it’s not just a relic from a bygone era, but it’s still actually very useful even in today’s brave new world.

So, what exactly is ‘string.format’ and why is it so special?

Well it’s not really ‘special’ it doesn’t have any *Super Cow* powers, and it’s never going to achieve world domination, BUT… it is exceptionally good at producing nicely formatted strings for all sorts of use cases.

Let’s start with a very simple example:

string FullName = "Peter" + " " + "Shaw";

It’s something that most of us have probably typed a million times over our career, but it’s a staple part of not just .NET but every language I’ve ever worked with.

Now let’s redo the same line, using string.format:

string FullName = string.Format("{0} {1}", "Peter", "Shaw");

Both lines achieve exactly the same thing, they make the variable ‘FullName’ be equal to ‘Peter Shaw’, and those of you who are letter count purists will most likely say, “Yuk, the string.format version is more letters, and so more typing.”

Those of you from the code neatness camp, will likely say, “But string.format is much more semantic, it conveys meaning and is easier to read.”

So in this case, which is better?

Well truth is, neither really, it’s all down to personal preference, that is until you start having to expand on the strings you’re producing.

Imagine if you will that our small example now forms part of an application that creates reports of some kind, and within that report you had quite a bit of data re-use; for example:

string ReportText = "Sales Figures by " + "Peter" + " " + "Shaw" +
                    " for the period Jan 2014 to March 2014, generated from sales agent " + "Peter" + " " + "Shaw" +
                    "using ID " + "Shaw" + "0001";

Ok, so maybe that’s a bit of a contrived example, but it illustrates the point I’m trying to make.

The word “Peter” has been re-used twice, and the word “Shaw” has been re-used three times.

Now, let’s take a look at the same thing done using string.format:

string ReportText =
  string.Format(
    "Sales figures by {0} {1} for the period Jan 2014 to Mar 2014, generated from sales agent {0} {1} using ID {1}0001",
    "Peter",
    "Shaw");

Immediately we see the benefit of only specifying the needed data twice instead of 5 times, now I don’t know about you but I’d rather just check that I’ve typed a string or variable name correctly once, than several times.

You can also see that from a code layout point of view; everything neatly lines up thus making it much easier to read, you know instantly that a ‘{0} = “Peter”‘ and like all good code, it practically documents itself.

So, now that you’re convinced that just maybe string.format deserves a little bit more love than it gets, I can show you what else it can do.

Let’s take the good old fashioned world of number formatting.

How many times have you done something like:

decimal Result = SomeComplexCalculationFunctionHere();
string PrintableNumber = Result.ToString();

Only to find that your output looks something like:

0.1264673826261817

Well, it may not surprise you that string.format has the answer to that one too.

string PrintableNumber = string.Format("{0:F3}", Result);

Will result in a number that looks like:

0.126

Because you’ve told string.format to use ‘F’ fixed point format with ‘3’ decimal places.

What about the following:

int Result = 20;
string PrintableNumber = string.Format("{0:D4}", Result);

If you guessed this right, then the output will have been:

0020

The ‘D’ means padded decimal integer and the ‘4’ means to 4 places, so you end up with a 4 digit printable number that’s prefixed with 0’s where needed.

Can things get any easier or better?

Yes they certainly can, let’s take for example the ‘X’ modifier:

int Result = 20;
string PrintableNumber = string.Format("{0:X}", Result);

Again, if you’ve guessed this correctly, the output should have been:

14

Wait, what? Since when did 14 = 20; when the number was automatically converted to hexadecimal for you that’s when 🙂

The format strings available can do everything from roundtrip numbers to display percentages and currency.

The last thing I’d like to show you about string.format is its date and time formatting abilities.

Lets take a look at the following:

string MyDate = string.Format("{0}", DateTime.Now);

By default that will produce:

14/04/2014 13:47:32

Which will be formatted according to your local culture settings.

Just as with the number formatting strings, there is a wide range of possible operators you can use here to get just the format you need; for example:

string MyDate = string.Format("{0:r}", DateTime.Now);

Will give you:

Mon, 14 Apr 2014 13:52:41 GMT

Where as:

string MyDate = string.Format("{0:s}", DateTime.Now);

Will give you:

2014-04-14T13:53:37

You can even format the date using individual separators and date parts to get a custom format

string MyDate = string.Format("{0:yyyy - dd MMMM @ hh:mm tt}", DateTime.Now);

Which will give you:

2014 - 14 April @ 01:57 PM

One thing you should also have noticed if you’ve made it this far, is that string.format in most cases also handles type conversion correctly; there’s no more needing to use ‘ToString’ or  one  of the ‘<type>.Convert’ methods to convert your data beforehand.

String.format is by far one of .NET’s hidden little gems, and yes its speed may not be as fast as a string builder or high memory access, but you may only be saving a couple of milliseconds in exchange for losing out on a whole world of rich data conversion and formatting.

If you have any ideas for this column, or there’s a topic you’d like to see covered, please feel free to hunt me down on twitter as @shawty_ds and ask me, I’m always open to ideas.

Shawty

More by Author

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Must Read