20

当我使用此代码时:

var ri = new RegionInfo("us");
var nativeName = ri.NativeName;   // ᏌᏊ ᎢᏳᎾᎵᏍᏔᏅ ᏍᎦᏚᎩ

那么为什么是nativeName字符串"ᏌᏊ ᎢᏳᎾᎵᏍᏔᏅ ᏍᎦᏚᎩ"(在Cherokee中)?

如果我更改为new RegionInfo("US")(only difference, capital US),我会得到"United States".

知道的首选用法RegionInfo是提供特定的文化信息字符串,例如:

new RegionInfo("en-US")
new RegionInfo("chr-Cher-US")

等等,这行得通。但是,为什么只有在我使用小写字母的情况下,切诺基语才比英语更受欢迎us


(见于 Windows 10(版本 1803“2018 年 4 月更新”)、.NET Framework 4.7.2。)


更新:即使在同一台机器上,这也不一致。例如,我多次尝试打开 PowerShell,每次都粘贴[System.Globalization.RegionInfo]'US'到其中。似乎很长一段时间以来,PowerShell 的所有实例都始终给出相同的结果。但过了一会儿,PowerShell 的实例又给出了相反的结果。这是两个窗口的屏幕截图,一个始终具有一个NativeName,另一个始终具有相反的一个。所以必须有一些不确定的决定(大小写没有区别):

PowerShell 窗口

4

1 回答 1

8

首先要注意的是,for 的构造函数RegionInfo通过查找该区域中使用的文化来查找该区域。所以它正在那个国家寻找一种语言,而不仅仅是这个国家。

通读该源代码,似乎大写/小写的差异是因为如果没有为区域指定文化,查找是如何完成的。

例如,它首先尝试几件事,然后它会尝试查看静态的区域列表。但是因为它使用Dictionary.ContainsKey的是 ,所以它是一个区分大小写的搜索。因此,如果您指定"US",它会找到它,但不会找到"us"

稍后,它会在所有文化(来自CultureInfo.GetCultures(CultureTypes.SpecificCultures))中搜索您提供的区域,但它以不区分大小写的方式进行搜索。

我无法确认,因为我无法单步执行该代码,但我的猜测是,因为它按顺序遍历列表,它会在到达chr-Cher-US之前到达en-US.

为什么不一致?

其中一条评论说,即使使用大写字母,LinqPad 也能找到 Cherokee。我不知道这是为什么。我能够复制它,但我也发现在 Visual Studio 中,使用时是英语,使用"US"时是 Cherokee "us",就像你描述的那样。但我确实发现,如果我在 LinqPad 中打开“使用实验性 Roslyn 程序集”,那么它会为"US""us". 所以也许它与目标的确切运行时版本有关,我不能肯定地说。

影响一致性的一件事是缓存:当文化+区域没有完全匹配时,它会做的第一件事是检查已经找到的文化的缓存。它将该缓存中的所有键都小写,因此该缓存不区分大小写。

你可以测试一下。我们知道使用"US"vs."us"会产生不同的结果,但是在同一个程序中试试这个:

var nativeNameus = new RegionInfo("us").NativeName;
var nativeNameUS = new RegionInfo("US").NativeName;

然后交换它们并再次运行它:

var nativeNameUS = new RegionInfo("US").NativeName;
var nativeNameus = new RegionInfo("us").NativeName;

两个结果将始终相等,因为第一个区域性被缓存并用于下一个区域性。

有可能在您的代码之外有代码调用相同的方法并最终缓存文化值,从而改变您执行相同操作时获得的结果。

结论

了这么多,文档实际上说

我们建议您使用区域性名称(例如,英语(美国)的“en-US”)来访问 NativeName 属性。

所以这是一个有争议的问题:你要求的是一个地区,而不是一种语言。如果您需要特定语言,请询问该语言,而不仅仅是一个地区。

如果你想保证英语,那么:

  1. 按照 Microsoft 的建议进行操作,并使用区域指定语言:“en-US”,或
  2. 使用EnglishNameorDisplayName属性(即使NativeName是 Cherokee 也是英语)。
于 2018-11-13T16:53:07.757 回答