C6.0 string interpolation localization
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
C# 6.0 string interpolation ($"Hello {name}") produces a culture-invariant string by default, which causes localization problems. Numbers, dates, and currencies get formatted using CultureInfo.CurrentCulture for the embedded expressions, but there is no built-in way to swap the interpolated string's template for a translated version. To localize properly, you need FormattableString to control culture formatting, and a separate localization system (resource files, IStringLocalizer) for the translated text itself.
String Interpolation Basics
The $"" syntax is syntactic sugar for string.Format():
The Localization Problem
Interpolated strings format numbers and dates using the current thread culture, but the template itself is hardcoded:
The number and date formatting respects culture, but "Price: " and "Date: " remain in English. For full localization, you need to translate the template too.
FormattableString for Culture Control
When you assign an interpolated string to FormattableString, C# preserves the format and arguments separately:
FormattableString.Invariant()
For data that must never be culture-dependent (API calls, file paths, SQL):
Localization with Resource Files
For translating the text template, use .resx resource files:
Note: You cannot use $"" interpolation with resource strings because the template must come from the resource file at runtime, not compile time.
ASP.NET Core IStringLocalizer
Custom Extension Method
Create a helper for culture-aware interpolation:
C# 10+ Interpolated String Handlers
C# 10 introduced custom interpolated string handlers for performance. They also enable custom culture handling:
Common Pitfalls
- Assuming
$""respects thread culture for text: Only the format specifiers (:C,:d,:N) use culture. The literal text in the template is always the compile-time string. - Using
$""for URLs and SQL: Culture-dependent decimal separators break URLs and SQL queries. Always useFormattableString.Invariant()for machine-readable output. - Confusing
stringandFormattableString:string msg = $"..."immediately formats to string. To preserve format+arguments, useFormattableString msg = $"...". - Resource files with wrong format indices: If the resource string uses
{0}and{1}, you must pass arguments in the same order withstring.Format. There is no compile-time checking like$""provides. - Mixed interpolation and concatenation:
$"Hello " + $"{name}"creates two separate strings and concatenates. Use$"Hello {name}"in one expression for clarity and performance.
Summary
$"..."formats embedded values usingCultureInfo.CurrentCulturebut the template text is always hardcoded- Use
FormattableStringto format with a specific culture:fs.ToString(culture) - Use
FormattableString.Invariant()for machine-readable output (URLs, APIs, SQL) - For full localization, use resource files (
.resx) withstring.Format()orIStringLocalizer - String interpolation cannot replace the template at runtime — use
string.Formatwith localized templates instead

