Интернационализация (i18n) в C# (.NET): Полное руководство
Интернационализация (часто сокращённо i18n — от английского «internationalization», где между первой буквой 'i' и последней 'n' находится 18 символов) — это процесс проектирования программного обеспечения таким образом, чтобы его можно было легко адаптировать под различные языки и региональные стандарты без внесения изменений в исходный код. В экосистеме C# (.NET) интернационализация является встроенной и мощной возможностью, позволяющей разработчикам создавать truly мультиязычные приложения.
В этой статье мы подробно рассмотрим, как реализовать i18n в .NET (включая .NET Core, .NET 5/6/7/8 и .NET Framework). Вы узнаете о ключевых концепциях — культурах, ресурсных файлах (RESX), локализации строк, изображений и форматировании данных.
Основные концепции
Прежде чем перейти к коду, важно понять два ключевых термина:
- Глобализация (Globalization): Процесс проектирования приложения, которое поддерживает локализованные интерфейсы и региональные данные для пользователей из разных культур. В .NET это достигается через классы
CultureInfoиRegionInfo. - Локализация (Localization): Процесс адаптации уже глобализированного приложения для конкретного языка/региона (например, перевод текстов, настройка форматов дат и валют).
.NET использует культуры (Cultures), которые задаются в формате язык-регион (например, ru-RU — русский (Россия), en-US — английский (США), de-DE — немецкий (Германия)).
Шаг 1: Создание ресурсных файлов (.resx)
Основной способ хранения локализованных строк в .NET — это ресурсные файлы (.resx). Они представляют собой XML-файлы, которые компилируются в сборку.
Рассмотрим пример. Создадим файлы для русского и английского языков:
- Resources.resx — файл ресурсов по умолчанию (обычно на английском).
- Resources.ru.resx — файл для русского языка.
- Resources.de.resx — файл для немецкого языка.
Внутри каждого файла мы добавим строковые ресурсы с одинаковыми именами, но разными значениями:
Resources.resx (язык по умолчанию — en-US):
Name: Greeting
Value: Hello, World!
Name: WelcomeMessage
Value: Welcome to our application!
Resources.ru.resx (Русский):
Name: Greeting
Value: Привет, мир!
Name: WelcomeMessage
Value: Добро пожаловать в наше приложение!
Шаг 2: Доступ к ресурсам в коде C#
.NET автоматически генерирует строго типизированный класс для доступа к ресурсам. Предположим, файлы находятся в папке Resources проекта. Тогда доступ будет выглядеть так:
using System;
using System.Globalization;
using System.Threading;
class Program
{
static void Main(string[] args)
{
// Устанавливаем культуру для текущего потока
Thread.CurrentThread.CurrentUICulture = new CultureInfo("ru-RU");
Thread.CurrentThread.CurrentCulture = new CultureInfo("ru-RU");
// Получаем локализованные строки
string greeting = Resources.Messages.Greeting;
string welcome = Resources.Messages.WelcomeMessage;
Console.WriteLine(greeting); // Выведет: Привет, мир!
Console.WriteLine(welcome); // Выведет: Добро пожаловать в наше приложение!
}
}
Обратите внимание: Resources.Messages — это автоматически сгенерированный класс, основанный на имени вашего RESX-файла (если файл называется Messages.resx).
Шаг 3: Локализация в ASP.NET Core
В веб-приложениях ASP.NET Core процесс интернационализации ещё более гибкий. Необходимо зарегистрировать сервисы локализации в Program.cs:
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using System.Globalization;
var builder = WebApplication.CreateBuilder(args);
// Добавляем сервисы локализации
builder.Services.AddLocalization(options => options.ResourcesPath = "Resources");
builder.Services.AddControllersWithViews()
.AddViewLocalization(); // Для локализации представлений (.cshtml)
var app = builder.Build();
// Настраиваем поддерживаемые культуры
var supportedCultures = new[]
{
new CultureInfo("en-US"),
new CultureInfo("