Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Compare a Cultures region without creating a RegionInfo from LCID

Tags:

c#

cultureinfo

For listing the applicable cultures for the given region, this is my current code:

public IEnumerable<CultureInfo> ForRegion(RegionInfo regionInfo)
{
     return CultureInfo.GetCultures(CultureTypes.SpecificCultures)
          .Where(c => Equals(new RegionInfo(c.LCID), regionInfo));
}

But I don't like having to create a RegionInfo in the Where.

I really want to do something this:

public IEnumerable<CultureInfo> ForRegion(RegionInfo regionInfo)
{
     return CultureInfo.GetCultures(CultureTypes.SpecificCultures)
          .Where(c => c.LCID == regionInfo.LCID);
}

But as there isn't an LCID on RegionInfo I can't. Aside from a better solution it would be interesting to know why a RegionInfo doesn't have an LCID.

Example test:

[TestMethod]
public void Can_find_all_by_region_ES_valencia()
{
    var regionInfo = new RegionInfo(new CultureInfo("ca-ES-valencia").LCID);
    List<CultureInfo> found = ForRegion(regionInfo).ToList();
    Assert.AreEqual(5, found.Count);
    CollectionAssert.AreEqual(
        new[]
        {
            new CultureInfo("ca-ES"),
            new CultureInfo("ca-ES-valencia"), //missing with Jon's solution
            new CultureInfo("es-ES"),
            new CultureInfo("eu-ES"),
            new CultureInfo("gl-ES")
        },
        found);
}

This works for my current solution but not Jon's.

Another two tests, fails for Jon's modified solution (work for original):

[TestMethod]
public void Can_find_all_by_region_Germany()
{
    List<CultureInfo> found = ForRegion(new RegionInfo("DE")).ToList();
    Assert.AreEqual(3, found.Count);
    CollectionAssert.AreEqual(
        new[] {new CultureInfo("de-DE"), new CultureInfo("dsb-DE"), new CultureInfo("hsb-DE")}, found);
}

[TestMethod]
public void Round_trip_all_cultures()
{
    foreach (CultureInfo culture in CultureInfo.GetCultures(CultureTypes.SpecificCultures))
        Assert.IsTrue(ForRegion(new RegionInfo(culture.LCID)).Contains(culture), culture.Name);
}
like image 647
weston Avatar asked Sep 26 '22 19:09

weston


1 Answers

This should be quite obvious from the results you get from your query - the same region can have multiple locales (and thus, LCIDs). So at best, you could get a list of LCIDs for a given region - and if you want to maintain that list, just make it yourself.

For example, region GB (United Kingdom) is home to three different locales - cy-GB (1106), gd-GB (1169) and en-GB (2057).

As far as performance goes, well... unless you can avoid all allocations in that Where of yours, there isn't much to tweak. Even a simple string.Split will likely cost you more than simply doing new RegionInfo. The culture data is cached, so there's only a memory cost associated with this kind of operation after the first time. And of course, again, there's nothing preventing you from building a lookup of your own, if you don't mind the memory cost.

like image 72
Luaan Avatar answered Sep 30 '22 06:09

Luaan