为什么你的C#应用程序需要国际化?
想象一下:你编写了一个很酷的笔记管理服务。一切运行正常,界面简洁,用户满意。但仅限于俄语用户。一旦进入美国或德国市场,项目就会停滞。不是因为代码不好,而是因为按钮 «Сохранить» 不会变成 «Save»,消息 «Ошибка ввода» 会吓到外国用户。
这就是本地化问题。在.NET世界中,其解决方案被称为 C#国际化(或i18n — 来自"internationalization"一词,18表示i和n之间的字母数量)。如果你使用C#和.NET平台(Core、5/6/7/8/9),你已经在底层拥有强大的工具包,可以让你的应用程序支持多语言。在本文中,我们将通过实践逐步讲解:从简单资源到"即时"切换语言。
基础知识:什么是区域性和中性语言
在编写代码之前,让我们先了解术语。在.NET中,System.Globalization命名空间中的两个关键类负责本地化:
- CultureInfo — 描述语言和区域标准的对象(例如
ru-RU、en-US、de-DE)。 - CurrentUICulture — 用户界面的当前区域性。系统在查找翻译时使用此属性。
- CurrentCulture — 日期、数字和货币的格式。这也可以更改,但对于翻译,第一个属性更重要。
在C#应用程序中,我们通常使用资源文件 (.resx)。这些是XML文件,存储与特定区域性关联的字符串、图像和其他数据。例如:
Messages.resx— 默认字符串(通常是英语)。Messages.ru.resx— 俄语翻译。Messages.de.resx— 德语翻译。
当应用程序启动时,.NET会自动选择与当前UICulture匹配的文件。如果没有完全匹配,则使用中性(基础)文件。
在Visual Studio中创建你的第一个资源文件
假设我们有一个控制台应用程序或ASP.NET Core项目。我们添加一个Resources文件夹,并在其中创建一个文件 Strings.resx。填写内容:
Name | Value
-------------|-------------------
WelcomeMsg | Welcome to our app!
GoodbyeMsg | Goodbye!
现在创建 Strings.ru.resx:
Name | Value
-------------|-------------------
WelcomeMsg | Добро пожаловать в наше приложение!
GoodbyeMsg | До свидания!
注意:键名必须匹配。保存后,Visual Studio会自动生成一个Strings类,通过静态属性访问字符串。
编程式语言切换
要使C#国际化生效,你需要在应用程序启动时(例如在Main或Startup中)设置所需的区域性。如下所示:
using System.Globalization;
using System.Threading;
// 设置俄语界面语言
CultureInfo culture = new CultureInfo("ru-RU");
Thread.CurrentThread.CurrentUICulture = culture;
Thread.CurrentThread.CurrentCulture = culture; // 用于日期/数字格式
// 现在访问资源
Console.WriteLine(Strings.WelcomeMsg); // 输出:Добро пожаловать в наше приложение!
如果你想允许用户"即时"切换语言(无需重启),只需在更改区域性后再次调用这些行即可。在ASP.NET Core中,使用中间件来实现:
app.UseRequestLocalization(new RequestLocalizationOptions
{
DefaultRequestCulture = new RequestCulture("en-US")