20 Apr 2015

In our code today we often work with strings and want to mix code with it. The simplest version of this is just concatenation of strings:

// it is okay when it is small
var result = "Hello " + Name;
// it looks messy when it gets long
var result2 = "You " + SubjectName + " must be the pride and joy of " + SubjectHomeTown;
// and when you take it across multiple lines... it is ugly
var result3 = @"This was a " + TestResult + @".
I am making a " + ReminderTool + @" here: 
" + SuccessRating;

String.Format is a potential help here:

// multiple data slugs 
return string.Format("{0} is {1} years old and their favourite animal is {2}", Name, Age, AnimalsOrderedByFavourite().First());

//using string.format for formatting
return string.Format("Hamsters cost {0:0.00}", 14.22);

The problem with string.format is that it is possible to make mistakes with the format items, for example:

// this line works but outputs the wrong data. There is NO way for the compiler to identify this & you get no exceptions when you run it.
string.Format("{0} is {0} years old and their favourite animal is {2}", Name, Age, AnimalsOrderedByFavourite().First());

// this line compiles fine, but it will raise a X exception when run as there is only three parameters and your are asking for a forth
string.Format("{0} is {3} years old and their favourite animal is {2}", Name, Age, AnimalsOrderedByFavourite().First());

String Interpolation to the rescue!

String Interpolation aims to make these scenarios easier by allowing you to have blocks of code directly inside the string itself. To achieve this we need to tell the compiler that the string may contain blocks of code, and we use the $ symbol prefixed on the string to do that. We can then insert blocks of code using the same braces we normally use for blocks of code. This allows us to change to code in the above examples to:

var result = $"Hello {Name}";
var result2 = $"You {SubjectName} must be the pride and joy of {SubjectHomeTown}";
var result3 = [email protected]"This was a {TestResult}.
I am making a {ReminderTool} here: 
{SuccessRating}";

return $"{Name} is {Age} years old and their favourite animal is {AnimalsOrderedByFavourite().First()}";

return $"Hamsters cost {14.22:0.00}";

In the above examples, it becomes clear what member what are working with and it is not possible for us to make mistakes as the compiler will run and identify the issues at compile time which are problems! It can also simplify things as with the third line where we use a continuation without having to have many @ symbols scattered around.

This is Code

This isn’t just a way to insert properties into strings, it is a way to insert code so you can do all kinds of interesting things with this:

// concat inside the code block
var example1 = $"Hello {Name + LastName}";

// calling methods
var example2 = $"Your home town is in {LookupProvinceState(SubjectHomeTown)}";

// async works too
var example3 = $"The temp is {await GetTemp()}";

// strings inside strings with interpolation
var example4 = $"Inception is {Rating + $"Inception is {Rating}"}";
// LINQ works & multi line works if you add an @
var example5 = [email protected]"LINQ works too {from a in AnimalsOrderedByFavourite()
                                 where a.Length > 20
                                  select a}";

// we can do string formatting
var example6 = $"Your balance is {Balance:C}";

The limitation here is that it must be a single statement. You cannot type a semicolon (;) in the string interpolation.

Syntactic Sugar

This, like so many of the C# 6 features is syntactic sugar and really it is just converting it to use string.format. For example out first example above becomes:

string text = string.Format("Hello {0}", new object[] {
    this.Name + this.LastName
});

What about Cultures? The answer is IFormattable

Looking at example six in the “This is Code” section, you can see we use the string formatting for currency but we cannot specify the culture information, so we cannot specify HOW to format it if we want to be specific. What is the solution? The result of the the interpolated string is a string which also implements IFormattable, and you can create a method to set the correct culture very easily:

static void Demo()
{
    // formatting as south african
    var example1 = en_za($"Your balance is {Balance:C}");
}

public static string en_za(IFormattable formattable)
{
    return formattable.ToString(null, new CultureInfo("en-za"));
}

In .NET 4.6, the string will also support System.Runtime.CompilerServices.FormattedString which will enable other options for formatting.

Tags: 

Add new comment