Beginner .Net Course: The String Format

Following the article on concatenation, we saw that it is very important to use StringBuilder for performance reasons. Here we will see how to format a string, a sentence, this formatting is often used.

Why String Format?

I won't tell you that it's more efficient; on the contrary, string.Format() costs a few extra milliseconds according to a simple test compared to a concatenated sentence:

string name = "Dupont";
string firstName = "Julie";
string address = "Rue de l'étoile";
string number = "10";
string postalCode = "75000";
string city = "Paris";

//I use Stopwatch to time my code
Stopwatch s = new Stopwatch();
//I start Stopwatch
s.Restart();
for(int i=0; i < 100000; i++)
{
string myMessage = string.Format("Hello {0} {1}, I am writing to ask you to send my package to {2}, {3} - {4} {5}",
                                   name, firstName, address, number, postalCode, city);
}
//I stop Stopwatch
s.Stop();
//I display the result
Console.WriteLine(String.Format("Time: {0}", s.Elapsed));
s.Restart();
for(int i=0; i < 100000; i++)
{
string myMessage = "Hello " + name + " " + firstName + ", I am writing to ask you to send my package to " +
                     address + ", " + number + " - " + postalCode + " " + city;
}
s.Stop();
Console.WriteLine(String.Format("Time: {0}", s.Elapsed));

//Result:
//string.format -> Time: 00:00:00.0378547
//concatenation -> Time: 00:00:00.0134245

The second part of the code is less readable than the first part of the code; did you notice that we use string.Format() instead of concatenating the variables (with +)?

The string.Format() is a good habit to adopt; it is much more readable, but you will see later that we can manage the output format of the string.

As we can see, it is enough to put between braces (or brackets) {x} the index of the value that will be replaced; be careful with this:

int i = 0;
int x = 100;
string.Format("My Value is {0}, however x is equal to {1}", i, x);

//Result:
//My Value is 0, however x is equal to 100

//Is not the same as this:

string.Format("My Value is {1}, however x is equal to {0}", i, x);
//Result:
//My Value is 100, however x is equal to 0

In the example above, on the second line, the first index is {1}, so it will not take i, because i is in position zero (and yes in computing, we always start from zero and not from 1), the position at {1} is x, while the index {0} is the value of position zero, so i.

Did you understand?

To summarize, we should avoid concatenations of this kind:

string name = "Dupont";
string firstName = "Julie";
string address = "Rue de l'étoile";
string number = "10";
string postalCode = "75000";
string city = "Paris";
string myMessage = "Hello " + name + " " + firstName + ", I am writing to ask you to send my package to " +
                                      address + ", " + number + " - " + postalCode + " " + city;
Console.WriteLine(myMessage);

//Result:
//Hello Dupont Julie, I am writing to ask you to send my package to Rue de l'étoile, 10 - 75000 Paris

But rather:

string name = "Dupont";
string firstName = "Julie";
string address = "Rue de l'étoile";
string number = "10";
string postalCode = "75000";
string city = "Paris";
string myMessage = string.Format("Hello {0} {1}, I am writing to ask you to send my package to {2}, {3} - {4} {5}",
                                    name, firstName, address, number, postalCode, city);
Console.WriteLine(myMessage);

//Result:
//Hello Dupont Julie, I am writing to ask you to send my package to Rue de l'étoile, 10 - 75000 Paris

Another advantage

Now it starts to get more interesting; thanks to string.Format(), we can directly format a value, like this:

int salary = 1000;
int workingHours = 16;
string myMessage = string.Format("My boss pays me {0:0.00}€ per month for {1:0#} h of work per day.", salary, workingHours);
Console.WriteLine(myMessage);
//My boss pays me 1000,00€ per month for 16 h of work per day.

workingHours = 1;
myMessage = string.Format("My boss pays me {0:0####.00}€ per month for {1:0#} h of work per day.", salary, workingHours);
Console.WriteLine(myMessage);
//My boss pays me 01000,00€ per month for 01 h of work per day.

myMessage = string.Format("Today is {0}", DateTime.Now);
Console.WriteLine(myMessage);
//Today is 23-04-19 16:53:54

myMessage = string.Format("Today is {0:dd-MM-yyyy}", DateTime.Now);
Console.WriteLine(myMessage);
//Today is 23-04-2019

As we can see, we can directly format the value as we wish, which would take longer during concatenation.

Another advantage is when you take a sentence from a database or a resource file, but this sentence must always contain different values, you just need to format it like this:

//Here we take a sentence from a resource file or even a database
//it doesn't matter where the sentence comes from, it's just an example
string.Format(resource.GetString("MySentenceInMyResourceFile"), address, postalCode, city);

//MySentenceInMyResourceFile = "I live in {0}, postal code {1}, city {2}"

Short variant

There is an even shorter version of string.Format() in C# 6 (Roslyn) starting from Visual Studio 2015 (you need to add the Microsoft.Net.Compilers package to use the new C# features):

string myMessage = string.Format("Today is {0:dd-MM-yyyy}", DateTime.Now);
Console.WriteLine(myMessage);
//Result: Today is 23-04-2019

myMessage = $"Today is {DateTime.Now:dd-MM-yyyy}";
Console.WriteLine(myMessage);
//Result: Today is 23-04-2019

The 2nd line presents a string.Format() that is slightly different, we start with the $ (dollar) sign and then the index that was zero in the first line is directly replaced and placed between the braces.

Format specifier Description Examples Result
C or c Currency string s = $"{2.5:C}";

string s = $"{-2.5:C}";
$2.50

($2.50)
D or d Decimal string s = $"{25:D5}"; 00025
E or e Exponential string s = $"{250000:E2}"; 2.50E+005
F or f Fixed-point string s = $"{2.5:F2}";

string s = $"{2.5:F0}";
2.50

3
G or g General string s = $"{2.5:G}"; 2.5
N or n Numeric string s = $"{2500000:N}"; 2,500,000.00
P or p Percentage string s = $"{0.25:P}"; 25.00%
R or r Round-trip string s = $"{2.5:R}"; 2.5
X or x Hexadecimal string s = $"{250:X}";

string s = $"{0xffff:X}";
FA

FFFF

And many more!

For more information on string.Format(), here is the documentation on the Microsoft site: https://docs.microsoft.com/fr-FR/dotnet/api/system.string.format?redirectedfrom=MSDN&view=netframework-4.8#System_String_Format_System_String_System_Object_

At compile time, it doesn't change anything, the dollar sign is transformed by a string.Format(), it's just a matter of habit, but I find it even more readable!

Aucun commentaire pour le moment.

Une erreur s'est produite. Cette application peut ne plus répondre jusqu'à ce qu'elle soit rechargée.Veuillez contacter l'auteur. Reload 🗙