[7/30/2015] This article was written against a pre-release version of C# 6.0. Be sure to check out the list of my five favorite C# 6.0 features for content written against the release!
I really debated about whether I should write about C#’s upcoming string interpolation feature yet. On one hand it’s an interesting feature that I’m looking forward to. On the other hand, it has already been announced that the feature is going to change from its implementation in the current preview. With that in mind I decided that it’s interesting enough to go ahead and write about it using the current syntax but highlight how it will change, much like how it has been done in the feature description document.
When I first heard that string interpolation was coming to C# I immediately experienced flashbacks to the very early days of my career when I was working with some Perl scripts. I really hated working with the language but something that always stuck with me and I missed when jumping to other languages was its string interpolation feature.
At a glance, Perl’s string interpolation feature let us embed variable names inside string literals and the compiler would handle the details of replacing the variable name with the value. My Perl is rusty to say the least but a simple example would essentially look like this:
my $name = "Dave"; print "My name is $name";
Upon execution, the script would write out the following text:
My name is Dave
Side note: I think this is the first time Perl has appeared on this blog. Hopefully it’ll be the last!
Perl’s implementation is more advanced than I’ve shown in this example but it clearly shows the usefulness of the feature. When .NET finally came along and I learned about String.Format I had hopes that it could evolve into something like the Perl feature described above. String.Format is certainly a useful method but it can quickly become a maintenance headache.
Traditional format strings have a number of problems each stemming from the index-based hole approach. First, each value must be supplied in the order that corresponds to the index which isn’t necessarily the order that the values appear in the string. Next, as the number of holes increases, it can be difficult to discern what each hole represents. This isn’t normally a problem for strings with only a few holes but consider the nightmare of keeping indices straight on a format string with more than 50 holes like I once encountered. Finally, String.Format validates only that enough values were supplied to fill each of the holes but if values were provided than there are holes there’s not even a compiler warning. Combine this with one of those 57-hole strings and good luck finding which indices are off or which values should be removed.
C#’s string interpolation aims to fix each of the aforementioned problems. The current implementation uses a slightly clunky version of the traditional format string syntax in that each hole must be prefixed with a backslash. Here’s how the previous example would be written in C# 6.0 using the syntax that’s in the current preview:
var name = "Dave"; WriteLine("My name is \{name}");
Just as in the Perl example, the compiler will resolve the name and fill the hole with the appropriate value. What’s more is that the compiler also verifies that each name exists in the current context and flags anything it can’t resolve as an error.
Per the upcoming features document, this syntax will be changed to something a bit friendlier. Rather than prefixing each hole with a backslash, the string will be identified as an interpolated string by prefixing it with a dollar sign like this:
var name = "Dave"; WriteLine($"My name is {name}");
In this trivial example the net effect on the code is moving and replacing a single character but it’s easy to imagine more complex interpolated strings becoming significantly shorter. (There will also be a FormattedString class added to the System.Runtime.CompilerServices namespace to facilitate custom formatting via the IFormattable interface but I won’t cover that in this article).
That interpolated strings (in either form) closely resemble traditional format strings is not entirely coincidental because ultimately, each interpolated string is syntactic sugar for invoking String.Format. Essentially, the compiler replaces each of the named holes with indexed holes and constructs the value array from the provided names. The benefit of this is that anything you can do with traditional format strings such as including alignment and format specifiers also is also possible with interpolated strings. For instance, we could easily represent a date in ISO 8601 format as follows:
"Current Date and Time (UTC): \{DateTime.UtcNow:o}"
So that’s C#’s string interpolation feature in a nutshell and I’m pretty excited about the direction it’s going because it’ll gradually clean up a lot of code. Since the feature is still under development there’s an active discussion in progress over on the Roslyn site. If you’re interested in seeing some of the thought process behind where this feature is going I encourage you to check it out.