Of course this is an ugly thing to do because a country (including your example "CH"
Switzerland) can have many languages.
Still, I will offer you two ugly methods. First one:
static IEnumerable<CultureInfo> FindCandidateCultures(RegionInfo region)
{
return CultureInfo.GetCultures(CultureTypes.SpecificCultures)
.Where(x => (new RegionInfo(x.Name)).GeoId == region.GeoId);
}
When used on your particular example, new RegionInfo("CH")
, it gives, on my version of the .NET Framework and my Windows version:
de-CH: German (Switzerland)
fr-CH: French (Switzerland)
gsw-CH: Alsatian (Switzerland)
it-CH: Italian (Switzerland)
rm-CH: Romansh (Switzerland)
wae-CH: Walser (Switzerland)
Edit: A later version gives the above, plus these two:
en-CH: English (Switzerland)
pt-CH: Portuguese (Switzerland)
The second method I will offer you:
// 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);
}
As is evident, it uses internal representations of mscorlib.dll
, and we never know if it will break with future versions. But it does give you a way to pick a particular culture. On my machine, from new RegionInfo("CH")
, you get it-CH: Italian (Switzerland)
.
Edit: Unsurprisingly, the second method has changed in some versions of .NET. Something like:
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));
or (if you use nullable reference types) with a lot of !
:
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)!);