String interpolation C# with Example



String interpolation C# with Example

String interpolation allows the developer to combine variables and text to form a string. 
Basic Example 
Two int variables are created: foo and bar. 
int foo = 34; 
int bar = 42; 
string resultString = $"The foo is {foo}, and the bar is {bar}."; 
Console.WriteLine(resultString); 
Output: 
The foo is 34, and the bar is 42. 
View Demo 
Braces within strings can still be used, like this: 
var foo = 34; 
var bar = 42; 
// String interpolation notation (new style) 
Console.WriteLine($"The foo is 
o}}, and the bar is {{bar}}."); 
 

This produces the following output: 
The foo is {foo}, and the bar is {bar}. 
Using interpolation with verbatim string literals 
Using @ before the string will cause the string to be interpreted verbatim. So, e.g. Unicode characters or line breaks 
will stay exactly as they've been typed. However, this will not effect the expressions in an interpolated string as 
shown in the following example: 
Console.WriteLine($@"In case it wasn't clear: 
\u00B9 
The foo 
is 
}, and the bar is {bar}."); Output: 
In case it wasn't clear: 
\u00B9 
The foo 
is 34, 
and the bar 
is 42. 
View Demo 
Expressions 
With string interpolation, expressions within curly braces {} can also be evaluated. The result will be inserted at the 
corresponding location within the string. For example, to calculate the maximum of foo and bar and insert it, use 
Math.Max within the curly braces:Console.WriteLine($"And the greater one is: th.Max(foo, bar) }"); 
Output: 
And the greater one is: 42 
Note: Any leading or trailing whitespace (including space, tab and CRLF/newline) between the curly brace and the 
expression is completely ignored and not included in the output 
View Demo 
As another example, variables can be formatted as a currency:Console.WriteLine($"Foo formatted as a 
currency to 4 decimal places: :c4}"); 
Output: 
Foo formatted as a currency to 4 decimal places: $34.0000 
 

View Demo 
Or they can be formatted as dates:Console.WriteLine($"Today is: eTime.Today:dddd, MMMM dd - yyyy}"); 
Output: 
Today is: Monday, July, 20 - 2015 
View Demo 
Statements with a Conditional (Ternary) Operator can also be evaluated within the interpolation. However, these 
must be wrapped in parentheses, since the colon is otherwise used to indicate formatting as shown above: 
Console.WriteLine($"{(foo > bar ? "Foo is larger than bar!" : "Bar is larger than foo!")}"); 
Output: 
Bar is larger than foo! 
View Demo 
Conditional expressions and format specifiers can be mixed: 
Console.WriteLine($"Environment: {(Environment.Is64BitProcess ? 64 : 32):00'-bit'} process"); 
Output: 
Environment: 32-bit process 
Escape sequences 
Escaping backslash (\) and quote (") characters works exactly the same in interpolated strings as in non- 
interpolated strings, for both verbatim and non-verbatim string literals: 
Console.WriteLine($"Foo is: }. In a non-verbatim string, we need to escape \" and \\ with backslashes."); 
Console.WriteLine($@"Foo is: {foo}. In a verbatim string, we need to escape "" with an extra quote, but we don't 
need to escape \"); 
Output: 
Foo is 34. In a non-verbatim string, we need to escape " and \ with backslashes. 
Foo is 34. In a verbatim string, we need to escape " with an extra quote, but we don't need to escape \ 
To include a curly brace { or } in an interpolated string, use two curly braces {{ or }}:$"{{foo}} is: }" 
Output: 
{foo} is: 34 
 

View Demo 
FormattableString type 
The type of a $"..." string interpolation expression is not always a simple string. The compiler decides which type 
to assign depending on the context:string s = $"hello, e}"; System.FormattableString s = $"Hello, {name}"; 
System.IFormattable s = $"Hello, {name}"; 
This is also the order of type preference when the compiler needs to choose which overloaded method is going to 
be called. 
A new type, System.FormattableString, represents a composite format string, along with the arguments to be 
formatted. Use this to write applications that handle the interpolation arguments specifically: 
public void AddLogItem(FormattableString formattableString) 
{ 
foreach (var arg in formattableString.GetArguments()) 
{ 
// do something to interpolation argument 'arg' 
} 
// use the standard interpolation and the current culture info 
// to get an ordinary String: 
var formatted = formattableString.ToString(); 
// ... 
} 
Call the above method with:AddLogItem($"The foo is }, and the bar is {bar}."); For example, one could choose not 
to incur the performance cost of formatting the string if the logging level was already going to filter out the log item. 
Implicit conversions 
There are implicit type conversions from an interpolated string:var s = $"Foo: }"; System.IFormattable s = $"Foo: 
{foo}"; You can also produce an IFormattable variable that allows you to convert the string with invariant 
context:var s = $"Bar: }"; System.FormattableString s = $"Bar: {bar}"; 
Current and Invariant Culture Methods 
If code analysis is turned on, interpolated strings will all produce warning CA1305 (Specify IFormatProvider). A 
static method may be used to apply current culture. 
public static class Culture 
{ 
public static string Current(FormattableString formattableString) 
{ 
return formattableString?.ToString(CultureInfo.CurrentCulture); 
} 
public static string Invariant(FormattableString formattableString) 
{ 
return formattableString?.ToString(CultureInfo.InvariantCulture); 
} 
} 
Then, to produce a correct string for the current culture, just use the expression:Culture.Current($"interpolated 
eof(string).Name} string.") Culture.Invariant($"interpolated {typeof(string).Name} string.") Note: Current and 
 

Invariant cannot be created as extension methods because, by default, the compiler assigns type String to 
interpolated string expression which causes the following code to fail to compile: 
$"interpolated {typeof(string).Name} string.".Current(); 
FormattableString class already contains Invariant() method, so the simplest way of switching to invariant 
culture is by relying on using static:using static System.FormattableString;p>string invariant = 
Invariant($"Now = {DateTime.Now}"); string current = $"Now = {DateTime.Now}"; 
Behind the scenes 
Interpolated strings are just a syntactic sugar for String.Format(). The compiler (Roslyn) will turn it into a 
String.Format behind the scenes: 
var text = $"Hello {name + lastName}"; 
The above will be converted to something like this: 
string text = string.Format("Hello {0}", new object[] { 
name + lastName 
}); 
String Interpolation and Linq 
It's possible to use interpolated strings in Linq statements to increase readability further. 
var fooBar = (from DataRow x in fooBarTable.Rows 
select string.Format("{0}{1}", x["foo"], x["bar"])).ToList(); 
Can be re-written as: 
var fooBar = (from DataRow x in fooBarTable.Rows 
select $"{x["foo"]}{x["bar"]}").ToList(); 
Reusable Interpolated Strings 
With string.Format, you can create reusable format strings: 
public const string ErrorFormat = "Exception caught:\r\n{0}"; 
// ... 
Logger.Log(string.Format(ErrorFormat, ex)); 
Interpolated strings, however, will not compile with placeholders referring to non-existent variables. The following 
will not compile: 
public const string ErrorFormat = $"Exception caught:\r\n{error}"; 
// CS0103: The name 'error' does not exist in the current context 
Instead, create a Func<> which consumes variables and returns a String: 
public static Func FormatError = 
error => $"Exception caught:\r\n{error}"; 
// ... 
 

Logger.Log(FormatError(ex)); 
String interpolation and localization 
If you’re localizing your application you may wonder if it is possible to use string interpolation along with 
localization. Indeed, it would be nice to have the possibility to store in resource files Strings like:"My name is e} 
{middlename} {surname}" instead of the much less readable: 
"My name is {0} {1} {2}" 
String interpolation process occurs at compile time, unlike formatting string with string.Format which occurs at 
runtime. Expressions in an interpolated string must reference names in the current context and need to be stored 
in resource files. That means that if you want to use localization you have to do it like: 
var FirstName = "John"; 
// method using different resource file "strings" 
// for French ("strings.fr.resx"), German ("strings.de.resx"), 
//  and  English  ("strings.en.resx") 
void ShowMyNameLocalized(string name, string middlename = "", string surname = "") 
{ 
// get localized string 
var localizedMyNameIs = Properties.strings.Hello; 
// insert spaces where necessary 
name = (string.IsNullOrWhiteSpace(name) ? "" : name + " "); 
middlename = (string.IsNullOrWhiteSpace(middlename) ? "" : middlename + " "); 
surname = (string.IsNullOrWhiteSpace(surname) ? "" : surname + " "); 
// display it 
Console.WriteLine($"{localizedMyNameIs} {name}{middlename}{surname}".Trim()); 
} 
// switch to French and greet John 
Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo("fr-FR"); 
ShowMyNameLocalized(FirstName); 
// switch to German and greet John 
Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo("de-DE"); 
ShowMyNameLocalized(FirstName); 
// switch to US English and greet John 
Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo("en-US"); 
ShowMyNameLocalized(FirstName); 
If the resource strings for the languages used above are correctly stored in the individual resource files, you should 
get the following output: 
Bonjour, mon nom est John 
Hallo, mein Name ist John 
Hello, my name is John 
Note that this implies that the name follows the localized string in every language. If that is not the case, you need 
to add placeholders to the resource strings and modify the function above or you need to query the culture info in 
the function and provide a switch case statement containing the different cases. For more details about resource 
files, see How to use localization in C#. 
 

It is a good practice to use a default fallback language most people will understand, in case a translation is not 
available. I suggest to use English as default fallback language. 
Recursive interpolation 
Although not very useful, it is allowed to use an interpolated string recursively inside another's curly brackets: 
Console.WriteLine($"String has {$"My class is called {nameof(MyClass)}.".Length} chars:"); 
Console.WriteLine($"My class is called {nameof(MyClass)}."); 
Output: 
String has 27 chars: 
My class is called MyClass. 

0 Comment's

Comment Form

Submit Comment