如何轻松、可靠地使用 .NET 中的文本资源






4.45/5 (8投票s)
本文档适用于支持国际化的 .NET 平台组件的开发人员。本文档对于那些使用资源文件和 String.Format 等函数处理 .NET 的人员也很有用。
演示所用任务的示例
我们有一个 Windows Forms 应用程序,它必须支持三种语言:英语、意大利语和俄语。因此,在应用程序的状态栏中,应以用户的区域语言打印以下字符串:“日期:{当前日期}”。
Microsoft 提供的解决方案
Microsoft 建议如下操作
- 为每种支持的语言创建一个 .resx 文件来存储文本资源。
- 在每个文件中添加一个带有通用资源标识符的字符串,例如“
IDS_DATE
”,并以正确的语言书写文本。例如,英文版本中的文本将是“Date: {0}”。 - 像这样编写代码
string messageTemplate = resourceManager.GetString( "IDS_DATE" ); string finalMessage = string.Format( messageTemplate, new DateTime() ); // Update the text in the status bar.
注意
可以找到关于 .NET 资源使用方式的信息。例如,此处。
看起来一切正常,但让我们更仔细地看看代码
- 如果更改资源中的标识符名称,或者代码中该名称的拼写有误,编译器不会报告任何错误,因为代码中该名称是以字符串形式存储的。
- 文本资源通常是消息模板。这些模板包含一些参数,并且由于模板是在单独的文件中声明的,因此会存在一个额外风险:在格式化模板时,参数的数量或顺序可能不正确。
ResxWrap - 解决此类问题的工具
ResxWrap 工具 - 用于从 .resx 文件生成文本资源类包装器 - 是为解决此类问题而创建的。类包装器使用户能够以更方便的方式处理资源。对于上述示例,只需编写以下代码即可
string finalMessage = generatedWrapper.IDS_DATE( new DateTime() );
// Update the text in the status bar.
这有什么变化?
- 我们只需一行代码,而不是两行。将例行代码量减半并非坏事。
- 如果更改标识符的名称,我们现在是安全的,因为编译器将报告错误,因为类包装器将不再包含
IDS_DATE
方法。 - 如果我们更改文本模板“
IDS_DATE
”中参数的数量,那也不会有问题。编译器将再次向我们显示错误消息,因为类包装器的相应方法签名也将更改。 - 在编辑方法调用时,可以查看每个参数的引用,以确保顺序正确。
如何生成类包装器
ResxWrap 是一个通过命令行参数管理的工具。回到我们的示例,假设我们的项目默认命名空间为“SampleApp”,项目文件位于目录“C:\My Projects\SampleApp”,并且资源文件名为“StringTable.resx”。因此,要生成类包装器,只需使用以下参数启动该工具即可
ResxWrap SampleApp "C:\My Projects\SampleApp\" StringTable
生成完成后,项目目录中将出现一个名为“__StringTable.cs”的新文件,其中将包含具有相同名称并在同一命名空间中声明的类的定义。
当然,也可以编写一个 .bat 文件,每次更改“StringTable.resx”后重新启动生成,但为了安全起见,最好在项目设置中添加到 Pre-build Event Command Line(预构建事件命令行)。为此,在我们的示例中只需编写
ResxWrap SampleApp ${ProjectDir} StringTable
让我们看看内部
生成的类包含
- 用于初始化
System.Resources.ResourceManager
类型受保护字段的构造函数; - 声明在 .resx 文件中的每个资源标识符的只读静态字段;
- 返回每个资源文本值的方法和只读属性。
如果文本字符串包含参数,则方法的签名将包含适当数量的参数以及文档注释。方法体除了加载文本消息模板外,还将包含对 String.Format
的调用,以准备消息的最终版本。
恢复
因此,如果您决定使用 ResxWrap 工具来开发项目,您必须
- 在项目文件中添加 ResxWrap 工具的调用;
- 重新编译项目;
-
将生成的类包装器文件添加到项目文件列表;
- 创建类包装器的实例;
- 调用适当的方法或属性来提取必要的文本资源。