C#6.0 string interpolation localization

An interpolated string evaluates the block between the curly braces as a C# expression (e.g. {expression}, {1 + 1}, {person.FirstName}).

This means that the expressions in an interpolated string must reference names in the current context.

For example this statement will not compile:

var nameFormat = $"My name is {name}"; // Cannot use *name*
                                       // before it is declared
var name = "Fred";
WriteLine(nameFormat);

Similarly:

class Program
{
    const string interpolated = $"{firstName}"; // Name *firstName* does not exist
                                                // in the current context
    static void Main(string[] args)
    {
        var firstName = "fred";
        Console.WriteLine(interpolated);
        Console.ReadKey();
    }
}

To answer your question:

There is no current mechanism provided by the framework to evaluate interpolated strings at runtime. Therefore, you cannot store strings and interpolate on the fly out of the box.

There are libraries that exist that handle runtime interpolation of strings.


According to this discussion on the Roslyn codeplex site, string interpolation will likely not be compatible with resource files (emphasis mine):

String interpolation could be neater and easier to debug than either String.Format or concatenation...

Dim y = $"Robot {name} reporting
{coolant.name} levels are {coolant.level}
{reactor.name} levels are {reactor.level}"

However, this example is fishy. Most professional programmers won't be writing user-facing strings in code. Instead they'll be storing those strings in resources (.resw, .resx or .xlf) for reasons of localization. So there doesn't seem much use for string interpolation here.


As already said in previous answers: you currently cannot load the format string at runtime (e.g. from resource files) for string interpolation because it is used at compile time.

If you don't care about the compile time feature and just want to have named placeholders, you could use something like this extension method:

public static string StringFormat(this string input, Dictionary<string, object> elements)
{
    int i = 0;
    var values = new object[elements.Count];
    foreach (var elem in elements)
    {
        input = Regex.Replace(input, "{" + Regex.Escape(elem.Key) + "(?<format>[^}]+)?}", "{" + i + "${format}}");
        values[i++] = elem.Value;
    }
    return string.Format(input, values);
}

Be aware that you cannot have inline expressions like {i+1} here and that this is not code with best performance.

You can use this with a dictionary you load from resource files or inline like this:

var txt = "Hello {name} on {day:yyyy-MM-dd}!".StringFormat(new Dictionary<string, object>
            {
                ["name"] = "Joe",
                ["day"] = DateTime.Now,
            });

Tags:

C#

.Net

C# 6.0