从国家/地区名称或RegionInfo对象获取CultureInfo对象

本文关键字:对象 获取 CultureInfo RegionInfo 国家 地区名称 | 更新日期: 2023-09-27 18:20:41

给定特定的国家/地区代码,例如"CH",如何获取CultureInfo对象?特定的国家/地区代码是动态的(在运行时更改)。我只有国家代码,我想知道是否可以从创建一个CultureInfo对象,只国家代码。我得到哪种确切的文化并不重要(fr-CH/de-CH)。

我正在尝试做这样的事情:

CultureInfo c = CultureInfo.CreateSpecificCulture("CH");

是否可以从RegionInfo对象创建区域性?然后看起来是这样的:

RegionInfo r= new RegionInfo("CH");
CultureInfo c = CultureInfo.CreateSpecificCulture(r);

显然,前面的例子并没有编译,它们只是给出了我想要实现的目标。

从国家/地区名称或RegionInfo对象获取CultureInfo对象

如果你只有国家/地区代码,你可以使用这样的东西来获取与该国家/地区相关的所有文化信息:

var cultureInfos = CultureInfo.GetCultures(CultureTypes.AllCultures)
                              .Where(c => c.Name.EndsWith("-CH"));

编辑:如@JeppeStigNielsen所指出的,在CH之前添加-以防止出现边缘情况(见下面的评论)。

您正在尝试创建CultureInfo对象吗?像这样:

CultureInfo c = new CultureInfo("de-CH"); //culture for  German (Switzerland)
CultureInfo c = new CultureInfo("fr-CH"); //culure for French (Switzerland)
CultureInfo c = new CultureInfo("it-CH"); //culture for Italian (Switzerland)

也许这个链接会有用http://www.csharp-examples.net/culture-names/它展示了所有的文化。

当然,这是一件丑陋的事情,因为一个国家(包括您的示例"CH"瑞士)可以有多种语言。

尽管如此,我还是会给你两种丑陋的方法。第一个:

static IEnumerable<CultureInfo> FindCandidateCultures(RegionInfo region)
{
  return CultureInfo.GetCultures(CultureTypes.SpecificCultures)
    .Where(x => (new RegionInfo(x.Name)).GeoId == region.GeoId);
}

当用于您的特定示例new RegionInfo("CH")时,它在我的.NET Framework版本和Windows版本上给出:

de CH:德语(瑞士)fr CH:法语(瑞士)gsw CH:阿尔萨斯(瑞士)it CH:意大利语(瑞士)rm CH:罗马语(瑞士)wae CH:Walser(瑞士)

编辑:稍后的版本给出了以上内容,加上这两个:

en-CH:英语(瑞士)pt CH:葡萄牙语(瑞士)

我将为您提供的第二种方法:

// ugly reflection, this can break any day!
static CultureInfo ConvertToCulture(RegionInfo region)
{
  var data = typeof(RegionInfo).GetField("m_cultureData", BindingFlags.NonPublic | BindingFlags.Instance)
    .GetValue(region);
  var name = (string)(data.GetType().GetProperty("SNAME", BindingFlags.NonPublic | BindingFlags.Instance)
    .GetValue(data));
  return CultureInfo.GetCultureInfo(name);
}

很明显,它使用了mscorlib.dll的内部表示,我们永远不知道它是否会与未来的版本决裂。但它确实给了你一种选择特定文化的方法。在我的机器上,从new RegionInfo("CH")可以得到it-CH: Italian (Switzerland)

编辑:不出所料,第二种方法在.NET的某些版本中发生了变化

var data = typeof(RegionInfo).GetField("_cultureData", BindingFlags.NonPublic | BindingFlags.Instance)
    .GetValue(region);
var name = (string)(data.GetType().GetProperty("CultureName", BindingFlags.NonPublic | BindingFlags.Instance)
    .GetValue(data));

或者(如果您使用可为null的引用类型)与许多!:

var data = typeof(RegionInfo).GetField("_cultureData", BindingFlags.NonPublic | BindingFlags.Instance)
    !.GetValue(region);
var name = (string)(data!.GetType().GetProperty("CultureName", BindingFlags.NonPublic | BindingFlags.Instance)
    !.GetValue(data)!);