[c#] Why use String.Format?

Why would anyone use String.Format in C# and VB .NET as opposed to the concatenation operators (& in VB, and + in C#)?

What is the main difference? Why are everyone so interested in using String.Format? I am very curious.

This question is related to c# string vb.net string.format

The answer is


I can see a number of reasons:

Readability

string s = string.Format("Hey, {0} it is the {1}st day of {2}.  I feel {3}!", _name, _day, _month, _feeling);

vs:

string s = "Hey," + _name + " it is the " + _day + "st day of " + _month + ".  I feel " + feeling + "!";

Format Specifiers (and this includes the fact you can write custom formatters)

string s = string.Format("Invoice number: {0:0000}", _invoiceNum);

vs:

string s = "Invoice Number = " + ("0000" + _invoiceNum).Substr(..... /*can't even be bothered to type it*/)

String Template Persistence

What if I want to store string templates in the database? With string formatting:

_id         _translation
  1         Welcome {0} to {1}.  Today is {2}.
  2         You have {0} products in your basket.
  3         Thank-you for your order.  Your {0} will arrive in {1} working days.

vs:

_id         _translation
  1         Welcome
  2         to
  3         .  Today is
  4         . 
  5         You have
  6         products in your basket.
  7         Someone
  8         just shoot
  9         the developer.

Besides being a bit easier to read and adding a few more operators, it's also beneficial if your application is internationalized. A lot of times the variables are numbers or key words which will be in a different order for different languages. By using String.Format, your code can remain unchanged while different strings will go into resource files. So, the code would end up being

String.Format(resource.GetString("MyResourceString"), str1, str2, str3);

While your resource strings end up being

English: "blah blah {0} blah blah {1} blah {2}"

Russian: "{0} blet blet blet {2} blet {1}"

Where Russian may have different rules on how things get addressed so the order is different or sentence structure is different.


First, I find

string s = String.Format(
    "Your order {0} will be delivered on {1:yyyy-MM-dd}. Your total cost is {2:C}.",
    orderNumber,
    orderDeliveryDate,
    orderCost
);

far easier to read, write and maintain than

string s = "Your order " +
           orderNumber.ToString() +
           " will be delivered on " +
           orderDeliveryDate.ToString("yyyy-MM-dd") +
           "." +
           "Your total cost is " +
           orderCost.ToString("C") + 
           ".";

Look how much more maintainable the following is

string s = String.Format(
    "Year = {0:yyyy}, Month = {0:MM}, Day = {0:dd}",
    date
);

over the alternative where you'd have to repeat date three times.

Second, the format specifiers that String.Format provides give you great flexibility over the output of the string in a way that is easier to read, write and maintain than just using plain old concatenation. Additionally, it's easier to get culture concerns right with String.Format.

Third, when performance does matter, String.Format will outperform concatenation. Behind the scenes it uses a StringBuilder and avoids the Schlemiel the Painter problem.


There's interesting stuff on the performance aspects in this question

However I personally would still recommend string.Format unless performance is critical for readability reasons.

string.Format("{0}: {1}", key, value);

Is more readable than

key + ": " + value

For instance. Also provides a nice separation of concerns. Means you can have

string.Format(GetConfigValue("KeyValueFormat"), key, value);

And then changing your key value format from "{0}: {1}" to "{0} - {1}" becomes a config change rather than a code change.

string.Format also has a bunch of format provision built into it, integers, date formatting, etc.


Several reasons:

  1. String.Format() is very powerful. You can use simple format indicators (like fixed width, currency, character lengths, etc) right in the format string. You can even create your own format providers for things like expanding enums, mapping specific inputs to much more complicated outputs, or localization.
  2. You can do some powerful things by putting format strings in configuration files.
  3. String.Format() is often faster, as it uses a StringBuilder and an efficient state machine behind the scenes, whereas string concatenation in .Net is relatively slow. For small strings the difference is negligible, but it can be noticable as the size of the string and number of substituted values increases.
  4. String.Format() is actually more familiar to many programmers, especially those coming from backgrounds that use variants of the old C printf() function.

Finally, don't forget StringBuilder.AppendFormat(). String.Format() actually uses this method behind the scenes*, and going to the StringBuilder directly can give you a kind of hybrid approach: explicitly use .Append() (analogous to concatenation) for some parts of a large string, and use .AppendFormat() in others.


* [edit] Original answer is now 8 years old, and I've since seen an indication this may have changed when string interpolation was added to .Net. However, I haven't gone back to the reference source to verify the change yet.


One reason it is not preferable to write the string like 'string +"Value"+ string' is because of Localization. In cases where localization is occurring we want the localized string to be correctly formatted, which could be very different from the language being coded in.

For example we need to show the following error in different languages:

MessageBox.Show(String.Format(ErrorManager.GetError("PIDV001").Description, proposalvalue.ProposalSource)

where

'ErrorCollector.GetError("ERR001").ErrorDescription' returns a string like "Your ID {0} is not valid". This message must be localized in many languages. In that case we can't use + in C#. We need to follow string.format.


String.Format adds many options in addition to the concatenation operators, including the ability to specify the specific format of each item added into the string.

For details on what is possible, I'd recommend reading the section on MSDN titled Composite Formatting. It explains the advantage of String.Format (as well as xxx.WriteLine and other methods that support composite formatting) over normal concatenation operators.


Examples related to c#

How can I convert this one line of ActionScript to C#? Microsoft Advertising SDK doesn't deliverer ads How to use a global array in C#? How to correctly write async method? C# - insert values from file into two arrays Uploading into folder in FTP? Are these methods thread safe? dotnet ef not found in .NET Core 3 HTTP Error 500.30 - ANCM In-Process Start Failure Best way to "push" into C# array

Examples related to string

How to split a string in two and store it in a field String method cannot be found in a main class method Kotlin - How to correctly concatenate a String Replacing a character from a certain index Remove quotes from String in Python Detect whether a Python string is a number or a letter How does String substring work in Swift How does String.Index work in Swift swift 3.0 Data to String? How to parse JSON string in Typescript

Examples related to vb.net

How to get parameter value for date/time column from empty MaskedTextBox HTTP 415 unsupported media type error when calling Web API 2 endpoint variable is not declared it may be inaccessible due to its protection level Differences Between vbLf, vbCrLf & vbCr Constants Simple working Example of json.net in VB.net How to open up a form from another form in VB.NET? Delete a row in DataGridView Control in VB.NET How to get cell value from DataGridView in VB.Net? Set default format of datetimepicker as dd-MM-yyyy How to configure SMTP settings in web.config

Examples related to string.format

Why use String.Format? Format decimal for percentage values? Equivalent of String.format in jQuery Is it better practice to use String.format over string Concatenation in Java? Python int to binary string? JavaScript equivalent to printf/String.Format Pad left or right with string.format (not padleft or padright) with arbitrary string