Globalization & Localization in .NET
Overview
.NET provides robust support for building applications that can adapt to different cultures, languages, and regional settings. This includes:
- Culture‑aware formatting of numbers, dates, and strings.
- Resource files for localizing UI text and assets.
- Automatic UI flow direction handling for right‑to‑left languages.
Working with CultureInfo
The System.Globalization.CultureInfo
class represents information about a specific culture. Use it to format data or to change the current thread’s culture:
using System;
using System.Globalization;
CultureInfo german = new CultureInfo("de-DE");
decimal price = 1234.56m;
Console.WriteLine(price.ToString("C", german)); // €1.234,56
Resource Files
Store localized strings in .resx
files. Create a base file (e.g., Resources.resx
) and additional files for each culture (Resources.fr.resx
, Resources.ja.resx
, …).
public class LocalizedStrings
{
private static ResourceManager _rm = new ResourceManager("MyApp.Resources", typeof(LocalizedStrings).Assembly);
public static string Welcome => _rm.GetString("Welcome");
}
Culture‑Aware Formatting
Use the String.Format
overload that accepts an IFormatProvider
or the ToString
overload with a format provider.
DateTime now = DateTime.Now;
Console.WriteLine(now.ToString("D", new CultureInfo("ja-JP"))); // 2025年9月10日
Complete Example
This sample demonstrates a simple console app that switches cultures at runtime and retrieves localized strings.
using System;
using System.Globalization;
using System.Resources;
using System.Threading;
class Program
{
static void Main()
{
// Simulate user selection
Console.WriteLine("Select language: (1) English (2) French");
var choice = Console.ReadKey().KeyChar;
CultureInfo selected = choice == '2' ? new CultureInfo("fr-FR") : new CultureInfo("en-US");
Thread.CurrentThread.CurrentCulture = selected;
Thread.CurrentThread.CurrentUICulture = selected;
ResourceManager rm = new ResourceManager("MyApp.Resources", typeof(Program).Assembly);
Console.WriteLine();
Console.WriteLine(rm.GetString("Greeting"));
Console.WriteLine(DateTime.Now.ToString("F"));
}
}
Best Practices
- Always use culture‑aware APIs; avoid
ToString()
without a provider. - Keep UI text out of code; use resource files.
- Test with
CultureInfo.InstalledUICulture
andCurrentCulture
variations. - Prefer
InvariantCulture
for persistence and protocols.