Skip to content

The CIL of C# 6.0’s String Interpolation

Effects of String Interpolation

One of the C# 6.0 features that will most simply and perhaps most predominantly affect the way you write C# code in the future is string interpolation.  Besides explaining composite string formatting (the old way – string.Format("{0} {1}", firstName, lastName) ) or obviously being relegated to a pre-C# 6.0 world, there is little reason to revert back from the string interpolation syntax.  Those of you previously writing code without the benefit of the new syntax, might be curious to learn how it is implemented.  In this regard I provide a brief introduction in my C# 6.0 article included in the Special December 2014 issue of MSDN Magazine:

"String interpolation is transformed at compile time to invoke an equivalent string.Format call. This leaves in place support for localization as before (though still with composite format strings) and doesn’t introduce any post compile injection of code via strings."

In addition to the localization remark, the important point about this description is that the string interpolation syntax doesn’t provide a means of passing format strings with string interpolation embedded expressions that introduce a mechanism for injecting arbitrary code into an assembly.  In other words, string interpolation doesn’t provide a mechanism, for example, to transform  string.Format("{0} {1}", firstName, lastName) to string.Format($"DeleteFile(".")", firstName, lastName)  for example.

What the description does not do justice on, however, is the internals of the compile time equivalent IL code generated by the C# compiler.  Although trivial, the code is not as equivalent as one might naively expect.  Consider, for example the following C# code:

    $"Your full name is {firstName} {lastName}.");

Converting this to System.Console.WriteLine("{0} {1}", firstName, lastName) is clearly not general enough and would require a numerous "switch" type cases.  However, because string.Format does not support the multitude of box-avoiding overloads that Console.WriteLine does, not only is an additional string.Format call necessary, but the array declaration and initialization of args is also necessary.  The resulting C# equivalent IL code, therefore, is as follows:

object[] args = new object[] { firstName, lastName };
Console.WriteLine(string.Format("Your full name is {0} {1}.", args));

Clearly, such verbosity is nothing to worry about unless in the most extreme of extreme performance scenarios.

On a side note, I am especially appreciative of the fact that string interpolation syntax doesn’t require special escape characters for "code" that appears in the expression blocks.  In other words, thanks goodness the syntax is simple enough that I don’t have to worry about escaping things like quotes in expressions that include said quotes such as System.Console.WriteLine("The file, {GetFullPath("HelloWorld.cs")} does not exist!"); .  (A statement that leverages C# 6.0’s using static System.IO.Path  of course.)

I am in the midst of writing Essential C# 6.0 and string interpolation is one of the changes that is permeating virtually every chapter, a change that I feel simplifies the code throughout, even if only minimally.


Comments are closed.