C#
string interpolation
compiler error
programming
debugging

Why does interpolating a const string result in a compiler error?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

In C#, an interpolated string ($"Hello, {name}") cannot be assigned to a const string because the compiler evaluates const values at compile time, and interpolated strings are converted to string.Format() or string.Concat() calls that execute at runtime. Constants can only be initialized with compile-time constant expressions — literal values, other constants, or constant operations. Starting with C# 10, interpolated strings of constant expressions can be const, but only if every interpolated value is itself a constant.

The Error

csharp
1const string name = "World";
2const string greeting = $"Hello, {name}!";
3// C# 9 and earlier: CS0133 - The expression being assigned to 'greeting'
4// must be a constant
5
6// C# 10+: This actually WORKS because 'name' is const

Before C# 10, all interpolated strings were treated as runtime expressions, even if every placeholder contained a constant. C# 10 added support for constant interpolated strings when all interpolated values are themselves const.

Why Interpolation Was Not Constant (Pre-C# 10)

csharp
1// The compiler transforms interpolated strings to:
2string greeting = $"Hello, {name}!";
3// becomes:
4string greeting = string.Format("Hello, {0}!", name);
5// or:
6string greeting = string.Concat("Hello, ", name, "!");
7
8// string.Format/Concat are method calls — not compile-time constants
9// Therefore the result cannot be assigned to const

The compiler did not evaluate interpolated strings at compile time. Even $"Hello, {"World"}" was treated as a method call, disqualifying it from const assignment.

C# 10: Constant Interpolated Strings

csharp
1// C# 10+ — this is valid
2const string firstName = "John";
3const string lastName = "Doe";
4const string fullName = $"{firstName} {lastName}";
5// fullName is "John Doe" at compile time
6
7// Also valid — nested constant interpolation
8const string greeting = $"Hello, {fullName}!";
9// greeting is "Hello, John Doe!" at compile time
10
11// NOT valid — variable is not const
12string dynamicName = "Alice";
13const string msg = $"Hello, {dynamicName}!";
14// CS0133: must be a constant expression

In C# 10+, the compiler evaluates constant interpolated strings at compile time if every {} expression resolves to a const value.

Workarounds for Pre-C# 10

csharp
1// Option 1: Use string concatenation with + operator
2const string name = "World";
3const string greeting = "Hello, " + name + "!";
4// This works because + on const strings is evaluated at compile time
5
6// Option 2: Use a single literal
7const string greeting2 = "Hello, World!";
8
9// Option 3: Use static readonly instead of const
10static readonly string greeting3 = $"Hello, {name}!";
11// Not a true constant, but works and is immutable

String concatenation with + on constant strings was always evaluated at compile time, making it the standard workaround.

const vs static readonly

csharp
1public class Config
2{
3    // const: value is baked into calling code at compile time
4    public const string Version = "1.0.0";
5
6    // static readonly: value is set once at runtime
7    public static readonly string Banner = $"App v{Version} - {DateTime.Now:yyyy}";
8
9    // const with interpolation (C# 10+)
10    public const string FullVersion = $"v{Version}-stable";
11}
Featureconststatic readonly
EvaluationCompile timeRuntime (once)
Interpolation (C# 10+)Only with const valuesAny expression
Can use runtime valuesNoYes
Stored in metadataYes (inlined)No (field reference)
Changes require recompileAll referencing assembliesOnly declaring assembly

When const Matters

csharp
1// Attribute arguments must be compile-time constants
2const string DefaultRole = "user";
3
4[Authorize(Roles = DefaultRole)]  // Works — const is compile-time
5public class UserController { }
6
7// static readonly does NOT work in attributes
8static readonly string role = "user";
9[Authorize(Roles = role)]  // Error: must be a constant expression
10
11// Switch case labels must be compile-time constants
12const string Admin = "admin";
13const string User = "user";
14
15switch (userRole)
16{
17    case Admin: break;   // Works
18    case User: break;    // Works
19}
20
21// Default parameter values must be compile-time constants
22void Greet(string name = "World") { }  // Works — literal
23// void Greet(string name = dynamicDefault) { }  // Error

Common Pitfalls

  • Assuming interpolation is always non-constant: In C# 10+, $"Hello, {constValue}" is a valid constant expression if constValue is itself const. Check your language version before applying workarounds that may not be needed.
  • Using static readonly when const is required: Attribute arguments, switch case labels, and default parameter values require compile-time constants. static readonly is not a compile-time constant and cannot be used in these contexts.
  • Forgetting that const values are inlined: When a const value from Assembly A is used in Assembly B, the value is copied into Assembly B at compile time. Changing the const in A without recompiling B leaves B with the old value. Use static readonly for values that may change between releases.
  • Mixing const and non-const in interpolation (C# 10+): $"{constPart}{nonConstPart}" is not constant because one expression is not const. All interpolated values must be const for the entire expression to be const.
  • Interpolating non-string types in const context: const int x = 42; const string s = $"{x}"; does not work even in C# 10 because int.ToString() is a method call. Only const string interpolation values are allowed in constant interpolated strings.

Summary

  • Interpolated strings cannot be const before C# 10 because they compile to string.Format() or string.Concat() calls
  • C# 10+ allows const interpolated strings when all interpolated values are themselves const string
  • For pre-C# 10, use + concatenation with const strings instead of interpolation
  • Use static readonly instead of const when you need runtime expressions in string construction
  • const values are inlined at compile time — changes require recompiling all referencing assemblies
  • Attribute arguments, switch labels, and default parameters require true compile-time constants

Course illustration
Course illustration

All Rights Reserved.