当我使用此代码时:
var ri = new RegionInfo("us");
var nativeName = ri.NativeName; // ᏌᏊ ᎢᏳᎾᎵᏍᏔᏅ ᏍᎦᏚᎩ
为什么是
nativeName
然后是字符串 "ᏌᏊ ᎢᏳᎾᎵᏍᏔᏅ ᏍᎦᏚᎩ"
(在 Cherokee 中)?
如果我更改为
new RegionInfo("US")
(仅区别,大写US
),我会得到"United States"
。
我do知道
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
,另一个窗口始终具有相反的一个。所以一定存在一些不确定性的确定(大小写没有区别):RegionInfo
构造函数通过查找该区域中使用的文化来找到该区域。因此,它正在寻找该国家/地区的语言,而不仅仅是该国家/地区。 通读该源代码,似乎大写/小写的差异是因为如果没有为该区域指定区域性,则如何完成查找。 例如,它首先尝试一些事情,但是
然后它会尝试
查找静态区域列表。但因为它使用 Dictionary.ContainsKey
,所以它是区分大小写的搜索。因此,如果您指定
"US"
,它会找到它,但不会找到 "us"
。
稍后,它会搜索所有文化(来自
CultureInfo.GetCultures(CultureTypes.SpecificCultures)
)以查找您指定的区域,但它以不区分大小写的方式进行搜索。
我无法确认,因为我无法单步执行该代码,但我的猜测是,因为它按顺序遍历列表,所以它会在到达
chr-Cher-US
之前到达 en-US
。为什么不一致?
其中一条评论说,即使使用大写字母,LinqPad 也能找到 Cherokee。我不知道这是为什么。我能够复制这一点,但我还发现在 Visual Studio 中,使用 "US"
"us"
时是切诺基语,就像您所描述的那样。但我确实发现,如果我在 LinqPad 中打开“使用实验性 Roslyn 程序集”,那么它会返回
"US"
和
"us"
的英语。所以也许它与目标的确切运行时版本有关,我不能肯定地说。
影响一致性的一件事是缓存:当它没有获得文化+区域的完全匹配时,它要做的第一件事是检查已找到的文化的缓存
。它将该缓存中的所有键都小写,因此该缓存不区分大小写。
你可以测试一下。我们知道使用 "US"
与
"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 属性。
所以这是一个有争议的问题:你要求的是一个地区,而不是一种语言。如果您需要特定语言,请询问该语言,而不仅仅是区域。如果你想保证英语,那么:
按照 Microsoft 建议进行操作并指定区域语言:“en-US”,或
使用
EnglishName
DisplayName
属性(即使 NativeName
是切诺基语,这些属性也是英语)。
我认为这是我第一次提出问题,所以希望我做得对。