(Not so) Stupid Question 283: What is string interpolation?
I had been stuck on some legacy projects and forgotten the world of sexy new language features until I started doing some work for a new client here in Gothenburg. While coding at a café my coding buddy for the day noticed some work I was doing and asked about the new string interpolation in C#.
A photo posted by Iris Classon (@irisclasson) on Jan 2, 2016 at 4:31am PST
So let’s talk string interpolation,- here is my best attempt at explaining and please do join in :) :
Interpolate comes from latin, interpolare and means ‘to give new appearance’ (‘to polish’). Interpolation is thus used to describe when one puts something between other things or parts, often more specifically inserting words into a text. This phrase becomes even more descriptive when we take a look at two alternatives also used, variable substitution and variable expansion.
FIY on the Stupid Question series:
In C# you might be familiar with composite formatting, functions that takes a list of objects and a string as input, and we can insert our objects into the string.
String.Format(“Hello {0}”, person.Name) is one example I’m sure you are more than familiar with.
C# 6 introduced string interpolation, a feature that has been around for quite some time in many languages- and it looks very much like templating albeit for smaller phrases :) JavaScript (for example) does have template strings ( string literals that allows you to embed expressions), and you can use string interpolation with them. But templating is not quite the same as interpolation.
JS
<span style="color: #800080;">var spinach = { bioavailability : 0.05, calcium : 300};
console.log(`From a cup of spinach only ${ spinach.calcium * spinach.bioavailability} mg of calcium is absorbed in calicium deficient subjects`);
</span>
C#
<span style="color: #800080;">var spinach = new {Bioavailability = 0.05, Calcium = 300};
</span>
<span style="color: #339966;">// ‘Manual’ string concat</span>
<span style="color: #800080;">Console.WriteLine("From a cup of spinach only " + (spinach.Calcium * spinach.Bioavailability) + " mg of calcium is absorbed in deficient subjects");</span>
<span style="color: #339966;">
// Composite formatting</span>
<span style="color: #800080;">Console.WriteLine("From a cup of spinach only {0} mg of calcium is absorbed in deficient subjects",(spinach.Calcium * spinach.Bioavailability));
</span>
<span style="color: #339966;">// String interpolation</span>
<span style="color: #800080;">Console.WriteLine($"From a cup of spinach only {spinach.Calcium * spinach.Bioavailability} mg of calcium is absorbed in deficient subjects");
</span>
So how does it really work? What is it doing in the background? Well, it’s more or less syntactic sugar (and very sweet sugar that is). Using TryRoslyn we can see that it does a String.Format(), and String.Format() uses a stringbuilder internally which uses the .AppendFormat() method to do exactly that.
<span style="color: #800080;">public static string Format(IFormatProvider provider, string format, params object[] args)
{
if ((format == null) || (args == null))
{
throw new ArgumentNullException((format == null) ? "format" : "args");
}
StringBuilder builder = new StringBuilder(format.Length + (args.Length * 8));
builder.AppendFormat(provider, format, args);
return builder.ToString();
}
</span>
Comments
So, to be clear then, this doesn't do anything other than giving you a "shortcut" for string.Format? I agree that the syntax is really nice, though!
Python: name = 'EvilKiru' print 'My name is %s.' %(name)
I think I agree with you, Steve, at least partially. At first look, this seems nice - just write the whole string you want in the order you want it - but I suspect that it may make the code more difficult to read. Might depend on how complex what you're inserting is; if you had something like: Console.WriteLine("His name was {Name} and he had been there for {Tenure} years") that reads pretty well. It's just the inline calculations that look messy.
@Steve For 1 or 2 parameter String.Formats, it's probably not too bad either way. But with more complex ones, I imagine that it's a lot easier to understand what the result will be if you can read inline with meaningful variable names, rather than needing to do the mental gymnastics to translate {0} {1} {2} ... Plus it's semantically identical to PowerShell string handling. A caveat is that you'd end up needing to go back the other way for doing internationalization/localization work.
Last modified on 2016-01-02