首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >比较区域性区域,而不从LCID创建RegionInfo

比较区域性区域,而不从LCID创建RegionInfo
EN

Stack Overflow用户
提问于 2015-09-07 11:19:18
回答 2查看 539关注 0票数 5

要列出给定区域的适用区域性,以下是我的当前代码:

代码语言:javascript
复制
public IEnumerable<CultureInfo> ForRegion(RegionInfo regionInfo)
{
     return CultureInfo.GetCultures(CultureTypes.SpecificCultures)
          .Where(c => Equals(new RegionInfo(c.LCID), regionInfo));
}

但我不喜欢在RegionInfo中创建Where

我真的很想这样做:

代码语言:javascript
复制
public IEnumerable<CultureInfo> ForRegion(RegionInfo regionInfo)
{
     return CultureInfo.GetCultures(CultureTypes.SpecificCultures)
          .Where(c => c.LCID == regionInfo.LCID);
}

但是,由于RegionInfo上没有RegionInfo,所以我做不到。除了一个更好的解决方案之外,了解为什么RegionInfo没有LCID会很有趣。

示例测试:

代码语言:javascript
复制
[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);
}

这适用于我目前的解决方案,而不是乔恩的解决方案。

另外两个测试,对于Jon的修改解决方案失败(原来的工作):

代码语言:javascript
复制
[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);
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-09-07 14:05:07

正如乔恩·斯基特( Jon )所指出的,RegionInfo是通过Name进行比较的。当您从一个RegionInfo创建LCID时,名称实际上来自LCIDCultureData上找到的一个属性。

因此,我添加了一个扩展方法(至少就我的目的而言,至少在我的解决方案中,我需要创建每个区域一次)从区域性中获取区域名称。

代码语言:javascript
复制
public static class CultureInfoExtension
{
    private static readonly Dictionary<int, string> RegionNamesByLcid =
        CultureInfo.GetCultures(CultureTypes.SpecificCultures)
            .Select(c => c.LCID)
            .Distinct()
            .ToDictionary(lcid => lcid, lcid => new RegionInfo(lcid).Name);

    private static string FallbackToThrowConsistentException(CultureInfo c)
    {
        return new RegionInfo(c.LCID).Name;
    }

    public static string GetRegionName(this CultureInfo c)
    {
        string name;
        return RegionNamesByLcid.TryGetValue(c.LCID, out name)
            ? name
            : FallbackToThrowConsistentException(c);
    }
}

用法:

代码语言:javascript
复制
public IEnumerable<CultureInfo> ForRegion(RegionInfo regionInfo)
{
    return CultureInfo.GetCultures(CultureTypes.SpecificCultures)
        .Where(c => CultureBelongsToRegion(c, regionInfo));
    }

    private static bool CultureBelongsToRegion(CultureInfo c, RegionInfo regionInfo)
    {
        return c.GetRegionName() == regionInfo.Name;
    }
}
票数 0
EN

Stack Overflow用户

发布于 2015-09-07 11:23:35

从您从查询中获得的结果来看,这是非常明显的--同一个区域可以有多个地区(因此,也可以是LCID)。因此,在最好的情况下,您可以获得给定区域的LCID列表-如果您想要维护该列表,只需自己创建它。

例如,GB地区(联合王国)有三个不同的地区-- cy-GB (1106)、gd-GB (1169)和en-GB (2057年)。

就表演而言,嗯.除非您能够避免您的Where中的所有分配,否则就没有什么可调整的了。即使是一个简单的string.Split,也可能比简单的new RegionInfo花费更多。区域性数据是缓存的,所以在第一次进行这种操作后,只需要占用一个内存成本。当然,如果你不介意内存成本的话,也没有什么能阻止你建立自己的查找。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32437412

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档