为什么ᏌᏊᎢᏳᎾᎵᏍᏔᏅᏍᎦᏚᎩ是美国的本土名称?

Jep*_*sen 20 .net c# globalization regioninfo casing

当我使用这段代码时:

var ri = new RegionInfo("us");
var nativeName = ri.NativeName;   // ?? ??????? ????
Run Code Online (Sandbox Code Playgroud)

nativeName那么为什么是弦乐"?? ??????? ????"(在切罗基)?

如果我改为new RegionInfo("US")(只有差异,资本US),我会改为"United States".

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

new RegionInfo("en-US")
new RegionInfo("chr-Cher-US")
Run Code Online (Sandbox Code Playgroud)

等等,这是有效的.但是,只有当我使用小写时,为什么切诺基比英语更喜欢us


(见于Windows 10(版本1803"2018年4月更新"),.NET Framework 4.7.2.)


更新:即使在同一台机器上,这也不一致.例如,我尝试打开PowerShell很多次,每次粘贴[System.Globalization.RegionInfo]'US'它.好像很长一段时间,PowerShell的所有实例都始终给出相同的结果.但过了一会儿,PowerShell的实例会产生相反的结果.这是两个窗口的屏幕截图,一个窗口始终有一个窗口,另一个窗口NativeName始终具有相反的窗口.因此必须有一些非确定性的决定(套管无差异):

PowerShell窗口

Gab*_*uci 8

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

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

例如,它首先尝试一些事情,但之后它会尝试查看静态的区域列表.但由于它正在使用Dictionary.ContainsKey,它是一个区分大小写的搜索.所以,如果你指定"US",它会找到它,但不是"us".

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

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

为什么不一致?

其中一条评论称,即使使用大写字母,LinqPad也会发现切诺基.我不知道为什么会这样.我能够复制它,但我也发现在Visual Studio中,使用"US"时是英文,使用时是切诺基"us",就像你描述的那样.但我发现,如果我把在LinqPad"使用实验罗斯林组件",则两个返回英语"US""us".所以也许它与目标的确切运行时版本有关,我不能肯定地说.

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

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

var nativeNameus = new RegionInfo("us").NativeName;
var nativeNameUS = new RegionInfo("US").NativeName;
Run Code Online (Sandbox Code Playgroud)

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

var nativeNameUS = new RegionInfo("US").NativeName;
var nativeNameus = new RegionInfo("us").NativeName;
Run Code Online (Sandbox Code Playgroud)

两个结果总是相同的,因为第一个文化被缓存并用于下一个文化.

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

结论

总而言之,文档实际上说:

我们建议您使用文化名称(例如,英语(美国)的"en-US")来访问NativeName属性.

所以这有点没有实际意义:你要求一个地区,而不是一种语言.如果您需要特定语言,请询问该语言,而不仅仅是某个地区.

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

  1. 按照Microsoft的建议并指定区域语言:"en-US"或
  2. 使用EnglishNameDisplayName属性(即使NativeName是切诺基时也是英语).