C# - Composite Formatting
Introduction
Composite formatting
uses numbered placeholders within a string.
- At run time, everything inside the braces is resolved to a value that is also passed in based on their position.
- This example of composite formatting uses a built-in method
Format()
on the string data type keyword.
1
2
3
4
5
6
string first = "Hello";
string second = "World";
string result = string.Format("{0} {1}!", first, second);
Console.WriteLine(result);
// Output: Hello World!
- There are a few important things to notice about this code.
- Data types and variables of a given data type have built-in
"helper methods"
to make certain tasks easy. - The literal string
"{0} {1}!"
forms a template, parts of which are replaced at run time. - The token
{0}
is replaced by the first argument after the string template, in other words, the value of the variable first. - The token
{1}
is replaced by the second argument after the string template, in other words, the value of the variable second.
- Data types and variables of a given data type have built-in
- You may think it’s odd to start with the number 0.
- Actually this is very common in software development.
- Whenever there’s a sequence of items that can be identified using a number, the numbering will usually start at 0.
- If you update the code as follows:
1
2
3
4
5
6
7
string first = "Hello";
string second = "World";
Console.WriteLine("{1} {0}!", first, second);
Console.WriteLine("{0} {0} {0}!", first, second);
// Output: World Hello!
// Output: Hello Hello Hello!
- A few observations about these examples:
- For the first
Console.WriteLine()
statement, observe that the tokens can be arranged in any order. - The sample code has
{1}
before{0}
. - For the second
Console.WriteLine()
statement, observe that the tokens can be reused with three instances of {0}. - Also, the second variable argument, second, isn’t used. Yet, the code still runs without error.
- For the first
What is string interpolation?
String interpolation
is a technique that simplifies composite formatting.- Instead of using a numbered token and including the literal value or variable name in a list of arguments to
String.Format()
orConsole.WriteLine()
, you can just use the variable name inside of the curly braces. - In order for a string to be interpolated, you must prefix it with the
$
directive. - Now, create the same examples from earlier using string interpolation instead of composite formatting.
- Update your code as follows:
1
2
3
4
5
6
7
8
9
string first = "Hello";
string second = "World";
Console.WriteLine($"{first} {second}!");
Console.WriteLine($"{second} {first}!");
Console.WriteLine($"{first} {first} {first}!");
// Output: Hello World!
// Output: World Hello!
// Output: Hello Hello Hello!
- If you look at code examples in books and online, you’re likely to see both composite formatting and string interpolation used, but generally you should choose string interpolation.
Formatting currency
- Composite formatting and string interpolation can be used to format values for display given a specific language and culture.
- In the following example, the
:C
currency format specifier is used to present the price and discount variables as currency. - Update your code as follows:
1
2
3
4
5
decimal price = 123.45m;
int discount = 50;
Console.WriteLine($"Price: {price:C} (Save {discount:C})");
// Output: Price: $123.45 (Save $50.00)
- Notice how adding the
:C
to the tokens inside of the curly braces formats the number as currency regardless of whether you use int or decimal.
- What happens if your country/region and language isn’t known?
- If you run the previous code in the “in-browser”
.NET
Editor, such as atTrydotNet
you’ll see the following output:Price: ¤123.45 (Save ¤50.00)
.- The symbol
¤
is used instead of the symbol for your country/region’s money.- This is a generic symbol used to denote
"currency"
regardless of the type of currency.- You see this symbol in the
.NET
Editor because it ignores your current location.
How the user’s country/region and language affect string formatting
- What if you execute the previous code on a computer in France that has its Windows Display Language set to French?
- In that case you would see the following output.
1
Price: 123,45 € (Save 50,00 €)
- The reason for the previous “€” output is that the string currency formatting feature is dependent on the local computer setting for culture.
- In this context, the term “culture” refers to the country/region and language of the end user.
- The culture code is a five character string that computers use to identify the location and language of the end user.
- The culture code ensures certain information like dates and currency can be presented properly.
For example:
- the culture code of an English speaker in the USA is
en-US
. - the culture code of a French speaker in France is
fr-FR
. - the culture code of a French speaker in Canada is
fr-CA
. - The culture affects the writing system, the calendar that’s used, the sort order of strings, and formatting for dates and numbers (like formatting currency).
- Unfortunately, making sure your code works correctly on all computers regardless of the country/region or the end user’s language is challenging.
- This process is known as
localization (or globalization)
. - Localization depends on many factors not discussed in this note, but simply, the string formatting syntax might use a different format depending on the user’s culture.
Formatting numbers
- When working with numeric data, you might want to format the number for readability by including commas to delineate thousands, millions, billions, and so on.
- The
N
numeric format specifier makes numbers more readable. - Update your code as follows:
1
2
3
4
decimal measurement = 123456.78912m;
Console.WriteLine($"Measurement: {measurement:N} units");
// Output: Measurement: 123,456.79 units
Formatting percentages
- Use the P format specifier to format percentages and rounds to 2 decimal places.
- Add a number afterwards to control the number of values displayed after the decimal point.
- Update your code as follows:
1
2
3
4
decimal tax = .36785m;
Console.WriteLine($"Tax rate: {tax:P2}");
// Output: Tax rate: 36.79%
Combining formatting approaches
- String variables can store strings created using formatting techniques.
- In the following example, decimals and decimal math results are formatted and stored in the yourDiscount string using composite formatting.
1
2
3
4
5
6
7
8
decimal price = 67.55m;
decimal salePrice = 59.99m;
string yourDiscount = String.Format("You saved {0:C2} off the regular {1:C2} price. ", (price - salePrice), price);
Console.WriteLine(yourDiscount);
// Output: You saved $7.56 off the regular $67.55 price.
- You can combine multiple formatted strings.
- Build on the previous code concatenating the calculated percentage using the string interpolation instead of string concatenation by inserting
yourDiscount += $"A discount of {(price - salePrice)/price:P2}!";
into the code on the line beforeConsole.WriteLine()
. - You don’t need to use String.Format() with this string interpolation approach.
- Update your code as follows:
1
2
3
4
5
6
7
8
9
decimal price = 67.55m;
decimal salePrice = 59.99m;
string yourDiscount = String.Format("You saved {0:C2} off the regular {1:C2} price. ", (price - salePrice), price);
yourDiscount += $"A discount of {((price - salePrice)/price):P2}!"; //inserted
Console.WriteLine(yourDiscount);
// Output: You saved $7.56 off the regular $67.55 price. A discount of 11.19%!
Examples
1
2
3
4
5
6
7
8
9
10
11
int invoiceNumber = 1201;
decimal productShares = 25.4568m;
decimal subtotal = 2750.00m;
decimal taxPercentage = .15825m;
decimal total = 3185.19m;
Console.WriteLine($"Invoice Number: {invoiceNumber}");
Console.WriteLine($" Shares: {productShares:N3} Product");
Console.WriteLine($" Sub Total: {subtotal:C}");
Console.WriteLine($" Tax: {taxPercentage:P2}");
Console.WriteLine($" Total Billed: {total:C}");
- The output of the previous code is as follows:
1
2
3
4
5
Invoice Number: 1201
Shares: 25.457 Product
Sub Total: $2,750.00
Tax: 15.83%
Total Billed: $3,185.19
This post is licensed under CC BY 4.0 by the author.