C# 10 First Look: Constant string interpolation

Constant string interpolation looks to be set for C# 10—let's take a look.

Dave Brock
Dave Brock

C# 9 is finally here, everybody.

This summer, we took a look at most of its core features. We looked at init-only features, records, pattern matching, top-level programs, and target typing and covariant returns.

Now, we can look forward to C# 10 (what is also referred to as C# Next). You probably think I’m crazy to be writing about C# 10 so early—and I am!—but there’s a feature slated for C# 10 that looks all set to go, constant string interpolation—a request that’s been hanging out on GitHub since 2015. Fred Silberberg from the Roslyn team says that it’s implemented in a feature branch and will likely be part of C# 10. As a matter of fact, if you head over to SharpLab, there’s a C# Next: Constant Interpolated Strings branch you can play with that’s been out there since … October 18, 2020.

While it’s madness to write about a new language feature so early, I don’t think it’s too crazy to talk about this specific feature. It’s super easy to implement so I don’t see that part changing too much—only when it gets shipped.

We’ll discuss the following content in this post.

Heads up! This should go without saying, but things may change between now and the C# 10 release date. In other words: 🤷‍♂️.

An absurdly quick example

These days—in C# 9 or earlier, that is—if you want to merge constant strings together, you will have to use concatenation, and not interpolation (or remove them as const variables altogether).

A common use is with paths. In current times, you have to do this if you are working with constant strings:

const string myRootPath = "/src/to/my/root";
const string myFilePath = myRootPath + "README.md";

With constant string interpolation, you can do this:

const string myRootPath = "/src/to/my/root";
const string myWholeFilePath = $"{myRootPath}/README.md";

Constant interpolated strings would be super convenient when working with attribute arguments. Let’s say you want to flag a method with the ObsoleteAttribute. Try this:

[Obsolete($"Ooh, don't use me. Instead, use {nameof(MyBetterType)}.")]

Why can’t I do that now?

When I learned about string interpolation back in C# 6, I was excited to think I’d never have to do concatenation again—so this is a bummer. Why can’t I do it, anyway?

If you try to use constant string interpolation in C# 9, you’ll get this error back:

error CS0133: The expression being assigned to 'myFilePath' must be constant

When you use string interpolation, the interpolated strings end up getting converted to string.Format calls. Once you understand that point, you’ll see it as:

const string myFilePath = string.Format("{0}/README.md", myRootPath);

While it may look like a constant at compile time, it isn’t because of the string.Format invocation. Of course, concatenation works fine since as there’s hardly any magic gluing two string literals together.

What about culture impacts?

While you may think that your string in question is just constants, you might be wrong and it might not be completely obvious. Even something as simple as outputting a float has impacts across cultures.

For example, here in the US I can do this:

Console.WriteLine($"{1200.12}") // output: 1200.12;

Try a different culture, and the results are different (and, to our point, not constant):

CultureInfo.CurrentCulture = new CultureInfo("es-ES", false);
Console.WriteLine($"{1212.12}"); // output: 1200,12

When it comes to constant string interpolation, will there be unintentional side effects when working with culture dependencies? The team insists that won’t be an issue:

This feature won’t work in this scenarios. It’ll only work for interpolating other constant strings, so locale is not a concern. It’s really just a slightly different syntax for string concatenation.

Wrap up

In this post, we looked at constant string interpolation—a promising addition to C# 10. We discussed how to use it, the reasons why you can’t use it now, and addressed culture impacts.

If you’re interested in what is currently slated for the next release of C#, head over to the Language Feature Status page in the Roslyn GitHub repo.

CSharp