我们可以跳过ResourceManager吗?

时间:2014-05-11 19:48:51

标签: c#

我正在开展一个项目,我正在广泛使用ResourceManager,这个问题在我脑海中浮现。 我们可以在不使用ResourceManager的情况下从.resx文件中读取吗?我的意思是,还有另一种方式吗?

4 个答案:

答案 0 :(得分:16)

ResourceManager是一个便利类,它与构建系统支持.resx文件的方式非常兼容。不,这不是一个严格的必要条件。

.NET程序集具有将任意数据嵌入到程序集清单中的通用功能。只需一个字节,它可以是你想要的任何东西。也可以由构建系统直接支持,只需将一个文件添加到项目中,并将其Build Action设置为“Embedded Resource”。在运行时,您使用Assembly.GetManifestResourceStream()检索该文件中的数据。

你可以在那里停留,但这只是一个文件,如果你想要嵌入很多小资源,它就不能很好地扩展。这是.resx文件启动的位置,它是一个XML文件,包含友好格式的资源。当原件丢失时,一个让你有机会再次恢复来源的机会。

但是XML格式对于资源数据来说不是一种非常好的格式,它体积庞大,找回数据的代价很高。所以.NET有resgen.exe,这是一个构建工具,可以将XML文件转换为二进制文件,即.resources文件。紧凑,易于找回的东西。并且适合作为单个清单资源直接嵌入。

想要做的是必须自己阅读.resources数据。您将需要使用可以从字节blob中找回特定资源的帮助程序类。您希望使用ResourceReader classGetResourceData()允许您指定资源名称,它会将资源类型和数据吐出来。

您可以在那里停留,但应用程序通常需要不同的资源集。非常常见的本地化需求。这是附属程序集的全部内容,不同的程序集只包含资源,每个程序集都适用于特定的文化。它们是分开的,因此当您只需要一组本地化资源时,您无需支付存储所有本地化资源所需的虚拟内存。这里需要的是一个帮助程序类,它根据当前文化自动定位并加载正确的附属程序集并为您检索资源。

帮助程序类是ResourceManager

答案 1 :(得分:6)

如果您选择跳过使用ResourceManager,可以让Visual Studio为您处理代码生成。最终生成的代码使用ResourceManager,但您不再手动编写该代码。此外,由于您引用了生成的静态类,因此您将获得编译时检查。

如果将资源文件添加到项目中并从解决方案资源管理器中双击它,Visual Studio将为您提供一个对话框,您可以在其中输入资源的名称及其值。该对话框为您提供了添加资源作为字符串,图像,音频等的选项(查看对话框顶部的下拉菜单)。接下来,要获取代码生成位,您需要将Access Modifier设置为“Public”或“Internal”。第三个选项是“无代码生成。”

例如,添加名为“MyResources”的资源文件,然后添加一个字符串资源,其中名称 Greeting {{1}使用前两个选项中的一个选择代码生成(从公共开始测试它,根据需要限制访问),您现在应该能够通过Hello!从代码中引用资源。如果您没有立即看到它,请确保已保存文件并尝试编译。

MyResources.Greeting

如果添加其他资源类型(图像,音频等),则返回类型当然会有所不同。

此时,您可以检查生成的string greeting = MyResources.Greeting; // "Hello!" 文件,看看生成的代码是否使用.cs。资源文件的另一个用途是本地化。假设你想要一个ResourceManager的西班牙语版本。您将添加一个名为MyResources的新文件,其中MyResources.es.resx对应于所需的语言代码(在本例中为西班牙语)。现在添加es的相同资源名称,其西班牙语值为Greeting

如果您将线程文化更改为西班牙语,则引用该资源现在将返回西班牙语版本:

Hola!

请注意,您只需将访问修饰符设置为默认资源文件的代码生成选项之一(即string defaultGreeting = MyResources.Greeting; // "Hello!" Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo("es"); string spanishGreeting = MyResources.Greeting; // "Hola!" ),而不是您添加的所有其他本地化版本。这样做没有任何害处,但在我看来,生成主文件更加清晰,而其他人只需拥有所需的资源值而无需生成代码。

答案 2 :(得分:2)

好的,资源被编译到程序集中。您可以尝试通过读取字节(或IL)来读取程序集,并从那里提取资源。

ResourceManager为你完成这一切,所以我想不出你想要这样做的任何理由......也许一个,如果你不想在内存中加载程序集,你可以在没有ResourceManager的情况下完成。 / p>

答案 3 :(得分:1)

Ref Microsoft:表示一个资源管理器,可在运行时方便地访问特定于区域性的资源。

我希望,我使用多郎,你会得到更一致的结果和更好的兼容性。

IMHO