C#、本地化、资源和MonoDevelop

10

我的问题是:我正在使用MonoDevelop(这是我正在处理的一些项目的首选环境),我想弄清楚如何使用资源文件来本地化消息,以及如何将它们作为嵌入式资源正确地包含在项目中。

我的目标是拥有一个资源文件,其中包含消息键和值的简单名称 - 值对,并且有用于它们本地化字符串的单独文件,例如:

Messages.resources

Hello.World = Hello World
Goodbye.Cruel.World = Goodbye, Cruel World

Messages.de.resources

Hello.World = Hallo Welt
Goodbye.Cruel.World = Auf Wiedersehen, grausame Welt

我遇到了一些问题。

首先,MonoDevelop的.resources文件和Visual Studio的资源概念有什么区别(如果有的话)?据我所知,MonoDevelop(和SharpDevelop)允许您创建.resources文件,而Visual Studio则使用.resx文件并通过resgen实用程序将它们编译成二进制文件类型的.resources文件。在MonoDevelop中使用资源时,是否需要使用resgen编译资源(例如Messages.resources)?当我尝试使用MonoDevelop通过向导创建的直接.resources文件时,会出现以下错误:

"Stream is not a valid resource file."

其次,一旦我生成了适当的资源文件,我可以将它们嵌入到我的项目中,这样如果我理解正确的话,资源就成为程序集的一部分。但是,如果我有两个文件Messages.resources和Messages.de.resources,至少在MonoDevelop中,它们被分配相同的ID值。我需要将默认语言环境包含在项目中,然后为每个支持的语言环境创建一个单独的项目吗?接下来,C#如何区分我的Messages.resources和Messages.de.resources文件(或任何其他文件)?

我目前正在尝试使用以下代码解决我的消息资源:

...
public string Translate(string messageKey, CultureInfo cultureInfo) {
    ResourceManager resourceManager = new ResourceManager("My.Project.Messages", Assembly.GetExecutingAssembly());
    string message = resourceManager.GetString(messageKey, cultureInfo);
    return message;
}
...

我觉得在使用C#进行国际化/本地化/全球化等方面,我似乎错过了一些基本要点。我以前在Java中曾经做过国际化项目,但出于某种原因,我无法完全理解如何在C#中实现。

另外,作为一个旁注,国际化项目中资源的“首选”目录结构是什么?

2个回答

3
我不熟悉.NET本地化(我使用gettext),但据我所知,.resources文件是一种二进制格式,实际上嵌入到您的dll中。您可以使用resgen将resx(XML)文本资源编译成二进制格式。文本文件更易读,但只能用于字符串资源。XML更冗长,但可以表示二进制资源的所有内容。
通常的做法是在项目中以.resx形式存储资源,当构建项目时,MonoDevelop会自动将其编译为.resources文件(您必须手动编译.txt文件)。不幸的是,MD没有专门的resx文件编辑工具,因此您必须直接编辑XML。
MD确实有很好的gettext本地化工具,但目前不支持Windows。

听起来好像如果我不想使用gettext(说实话,这听起来是解决这个问题最简单和最直接的方法),我可以利用类似于Visual Studio所使用的.resx文件,而MonoDevelop将负责将它们编译成.resources文件。 - Sean Quinn
你能否就MonoDevelop允许您通过“新文件>杂项>空资源文件”选项创建的.resources文件与.txt、.resx或.resources(二进制)与Visual Studio类似命名的文件类型之间的关系进行解释吗? 我认为MonoDevelop的空资源文件更接近于.txt文件,而不是.resx文件(最终仍然只是文本文件),也不是二进制.resources文件。感谢您提供的任何见解,这对我造成了很多困惑。 - Sean Quinn
这个空的 .resources 文件看起来像是从 SharpDevelop 继承而来的,它确实有一个用于二进制资源的编辑器。如果它在文本编辑器中打开,那很可能是一个 bug。 - Mikayla Hutchinson
听起来可能是一个 bug,它在 MonoDevelop 的文本编辑器中打开了 .resources 文件。知道 SharpDevelop 支持二进制的 .resources 文件是很好的,这很可能是 MonoDevelop 继承自 SharpDevelop 代码的遗留问题。至少这解决了一些困惑,谢谢! - Sean Quinn

0

据我所了解,根据MonoDevelop自己的承认,Gettext在Windows环境下存在一些限制。或者说,编辑翻译和更新翻译的工具只能从Linux访问。这些限制仍然存在吗?它们有多真实?阅读后,Gettext似乎应该足够满足我的需求,但我需要深入挖掘一下。 - Sean Quinn
@mhutch 我正在运行 MonoDevelop 2.6 beta 3,看起来在我的 Windows 环境中可以使用翻译项目。似乎在 2.2 版本中不支持,但在 2.6 版本中已经支持了吗? - Sean Quinn
@mhutch...另外,我是否正确地假设Gettext本地化实现中的“fallback”文本也充当.po文件中的标识符,驻留在源代码中?这种方法是否会将实际文本与源代码紧密耦合?在我参与的Java项目中,我们有非常简单的键值对文本文件,只通过它们的键标识符与应用程序耦合,所有文本和翻译都在这些文本文件中(从不在实际源代码中);这使得翻译人员可以远离源代码。看起来Gettext通常不是这样工作的。 - Sean Quinn
是的,文本中的字符串是默认语言环境中使用的字符串。这对程序员来说更加方便,对翻译人员来说并不重要,因为他们不需要查看源代码,只需要查看po文件即可。 - Mikayla Hutchinson
你和Nicolas在帮助我理解MonoDevelop本地化的一些细节方面非常有帮助。目前我会将你之前的回答标记为已接受的答案,因为它最清晰易懂。再次感谢! - Sean Quinn
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接