本地化.NET;使用 ResourceManager 时的后备语言

发布于 2024-08-21 16:29:33 字数 1188 浏览 4 评论 0原文

最近我正在研究 .NET 本地化。本质上,我学习了如何自定义表单(使用语言和可本地化属性),然后相应地更改文化。

然而,我发现当将我的硬编码英文字符串迁移到自动生成的资源文件中并使用 .GetString("Key") 时——好吧,我们只是说它不高兴:P。

我决定制作一组单独的 resx 文件,专门用于硬编码字符串翻译。他们遵循 [name].[culture-code].resx 的约定/要求。我为每种相关语言制作了这些;例如appstrings.de.resx(德语)和appstrings.resx(作为不变基线)。

为了利用这些新资源,我创建了一个 ResourceManager 和资源集的实例。

Dim resManager As New ResourceManager("LanguageTest.appstrings", Assembly.GetExecutingAssembly)
Dim resSet As ResourceSet = resManager.GetResourceSet(My.Application.UICulture, True, True)

设置的(例如,德语),

My.Application.ChangeUICulture("de")

当前的 UI 区域性是使用原始问题

除非明确 resSet.GetString("Key")在 appstrings.de.resx 中定义,它将返回一个空白字符串。无论如何,我是否可以将其回退到 appstrings.resx (其中“Key”确实存在),我认为这是默认基线?

更新

Rhapsody 在下面提出了一个建议,虽然实际的提示本身不起作用,但它实际上引发了一个有趣的观点,使用 resManager.GetString("Key") 而不是 resSet.GetString( “钥匙”)。到目前为止,这似乎没有任何缺陷。也就是说,返回专用语言文件中存在的值,而当通过单个键访问时,“缺失”值会回退到默认区域性。

后续问题

唯一剩下的问题是使用 ResourceManger 而不是缓存的 ResourceSet 对性能的影响是否会那么有害?

Recently I was delving into Localization with .NET. Essentially, I learnt how to customize a form (using the Language and Localizable property) and then change the culture accordingly.

However, I found that when migrating my hard coded English strings into the auto-generated resource files, and use .GetString("Key") -- well, let's just say it wasn't happy :P.

I decided to make a separate set of resx files dedicated purely to the hard coded string translations. They followed the convention/requirement of [name].[culture-code].resx. I made of of these for each relevant language; e.g. appstrings.de.resx (For German) and appstrings.resx (as invariant baseline).

To utilise these new resources, I created an instance of ResourceManager and Resource Set

Dim resManager As New ResourceManager("LanguageTest.appstrings", Assembly.GetExecutingAssembly)
Dim resSet As ResourceSet = resManager.GetResourceSet(My.Application.UICulture, True, True)

The current UI culture was set (for example, to German) using

My.Application.ChangeUICulture("de")

Original issue

Unless the resSet.GetString("Key") is explicitly defined in the appstrings.de.resx, it will return a blank string. Is there anyway I can make it fallback to the appstrings.resx (where "Key" does exist), which I assumed would be the default baseline?

Update

Rhapsody made a suggestion below, while the actual tip itself didn't work, it did in-fact spark an interesting point, using resManager.GetString("Key") as opposed to resSet.GetString("Key"). This appears to work without flaw so far. That is, values present in the specialized language file are returned, while 'missing' values fall-back to the default culture when accessed by a single key.

Subsequent Issue

The only remaining issue would be whether the performance impact of using ResourceManger as opposed to a cached ResourceSet will be that detrimental?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

手心的温暖 2024-08-28 16:29:33

您可以尝试为应用程序声明默认区域性,如下所示。

[assembly: NeutralResourcesLanguageAttribute("en-US", UltimateResourceFallbackLocation.Satellite)]

此代码声明您的默认区域性是 en-US。在您的示例中,如果当前区域性是“de-DE”,它将在“de-DE”中查找资源,然后查找父级“de”区域性,依此类推,最终转到定义的区域性(en-US)资源文件。 请参阅 MSDN 了解资源管理的后备策略。
上面的代码通常位于 assenblyInfo.cs 中。第二个参数告诉资源管理器资源位于主程序集或卫星中的位置。

不幸的是,在此解决方案中,您必须使用区域性名称,而不是资源文件名。但是,您可以扩展 RM 以通过文件名使用特定资源,但选择默认区域性并将资源文件重命名为该区域性更简单,并且您拥有开箱即用的解决方案。

You can try declaring a default Culture for the application as below

[assembly: NeutralResourcesLanguageAttribute("en-US", UltimateResourceFallbackLocation.Satellite)]

This code declares that your default culture is en-US. In your example if current culture is "de-DE" it looks for for resource in "de-DE", then looks for the parent "de" culture and so on and Ultimatly goes to the defined culture (en-US) resource file. see MSDN for fallback strategies by resourceManage.
The above code normaly goes in the assenblyInfo.cs. The second parameter is telling the resource manager where are the resources located in Main assembly or satellite.

Unfortunatly in this solution you have to use a culture name, Not the resource file name. however you could extend RM to use a specific resource by file name, But its way simpler to pick a default culture and rename your resource file to that culture and you have the solution out of the box.

攒一口袋星星 2024-08-28 16:29:33

尝试

Public Function GetString(ByVal Name As String) As String
    Return My.Resources.Strings.ResourceManager.GetString(Name)
End Function

其中 Strings 是项目中 resx 文件的名称。
当基线值不适用于当前区域性时,这将自动返回基线值。

这是一个简单的例子,你可能想让它更加简单。

Try

Public Function GetString(ByVal Name As String) As String
    Return My.Resources.Strings.ResourceManager.GetString(Name)
End Function

Where Strings is the name of the resx files in your project.
This will automatically return the baseline value when it's not available for the current culture.

It's an easy example, you might want to make it more fool proof.

一身仙ぐ女味 2024-08-28 16:29:33

我曾经创建了一个 Web 应用程序,它以 en-US 作为后备语言,但有其他更具体的语言,例如基于用户 Web 浏览器中的设置的 .de

基本上为了让它工作,我在 web.config 中设置了 xml

<globalization uiCulture="auto" culture="auto" requestEncoding="utf-8" responseEncoding="utf-8"/>

从那里我使用.cs 文件中的内部静态 ResourceManager 是随默认语言一起提供的,例如

Resources.<ResourceFileName>.ItemSearchNoResultsErrorText

在 .aspx 文件中:

<%$ Resources:<ResourceFileName>, TimeSelect %>

据我了解,包含 ResourceManager 类的 .cs 文件所在的位置很重要,它是否位于 .de 后面语言文件或后备语言?由于它是作为单独的附属程序集进行编译的,因此它取决于 .cs 类的编译位置以及它属于哪个附属程序集。

通常,我总是将 ResourceManager 类作为 en-US 语言的代码隐藏,因为如果找不到更具体的语言,我想将其用作后备语言

使用此设置我从未获得过空白值,它始终使用后备语言,即使我在运行时交换附属程序集。

I once created a web application which had en-US as the fallback language but have other more specific ones like .de based on the settings in the users web browser

Basically to get it working I set the xml in web.config

<globalization uiCulture="auto" culture="auto" requestEncoding="utf-8" responseEncoding="utf-8"/>

From there I used the internal static ResourceManager from the .cs file which is provided with your default language, e.g.

Resources.<ResourceFileName>.ItemSearchNoResultsErrorText

and in .aspx files:

<%$ Resources:<ResourceFileName>, TimeSelect %>

As I understand it then it is significant where your .cs file which contains the ResourceManager class lives, is it behind the .de language file or the fallback language ? Since it's compiles as a seperate satellite assembly then it is depended on where the .cs class is compiled and what satellite assembly it is a part of.

As a rule I've always had the ResourceManager class as a code behind on the en-US language because that's the one I want to use as the fallback language if the more specific ones are not found

Using this setup I've never got a blank value, it's always used the fallback language, even though I swap out the satellite assemblies at runtime.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文