CultureInfo.CreateSpecificCulture()和类的构造函数之间有什么区别?

41

CultureInfo 有两种创建方式:

MSDN 对这两种方法的文档略有不同,对于构造函数提到了一些“Windows 文化”。但这真的要紧吗?

我应该更喜欢其中的某一个吗?

注意:如果有影响的话,我正在使用 .NET 版本 3.5,并且我想像这样使用它:

Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture(culture);
Thread.CurrentThread.CurrentUICulture = new CultureInfo(culture);

此回答中所述。

3个回答

34
工厂方法在创建区域性信息失败时有一个后备方案。
因此,如果您使用特定的区域设置,例如'en-XX',则无法创建区域性信息实例,将引发异常,并且使用中性区域' en '进行重试将成功。
下面是工厂方法的source
public static CultureInfo CreateSpecificCulture(string name)
{
    CultureInfo info;
    try
    {
        info = new CultureInfo(name);
    }
    catch (ArgumentException)
    {
        info = null;
        for (int i = 0; i < name.Length; i++)
        {
            if ('-' == name[i])
            {
                try
                {
                    info = new CultureInfo(name.Substring(0, i));
                    break;
                }
                catch (ArgumentException)
                {
                    throw;
                }
            }
        }
        if (info == null)
        {
            throw;
        }
    }
    if (!info.IsNeutralCulture)
    {
        return info;
    }
    return new CultureInfo(info.m_cultureData.SSPECIFICCULTURE);
}

所以我更喜欢工厂方法。

2
你是对的,工厂方法可以处理这个问题,正如我的测试所示。然而,回退只适用于区域部分,任何一种有缺陷的中性文化都无法被处理。 - Marcel
我现在使用建议的工厂方法。我已经对所有相关文化进行了单元测试,它可以正常工作。 - Marcel
2
我注意到对于 CreateSpecificCulture("en") 返回 en-us,而 new CultureInfo("en") 则似乎返回一个不变的英语。 - Dirk Boer
2
@DirkBoer是正确的。这个答案没有涵盖到有两种文化,__中性__文化(如en)和__特定__文化(如en-USen-GBen-AU)。检查属性IsNeutralCulture以找出。请注意,在此答案的引用源代码中,我们在try-catch结构之后检查它是否是中性文化,如果是,则创建另一个具体的文化,从内部成员字段的internal属性SSPECIFICCULTURE中获取。请参见我在其他地方发布的帖子以获取示例。 - Jeppe Stig Nielsen
2
因此,如果您想要中性或特定文化(包括特殊的“不变文化”)之一,请使用 new CultureInfo(culture)。如果您想避免中性文化,请使用 CultureInfo.CreateSpecificCulture(culture) - Jeppe Stig Nielsen

7
这个帖子已经有了答案,但是我发现了CreateSpecificCulture API的一个独特发现,有时可能不太明显。因此,我认为这个帖子是我发现的一个合适的地方。我花了几天时间研究这个问题,所以想分享一下我的经验,如果能为其他人节省几个小时或几天的时间就好了。
当您只传递区域设置名称(如pt(葡萄牙语)或de(德语))给API时,该API返回相应于该区域设置的特定区域设置,该区域设置被称为该区域设置的默认区域设置。现在,这个区域设置可能并不像听起来那么明显,这就是我卡住的地方。对于德语而言,de-DE看起来很明显,它是在德国讲德语。对于意大利语而言,it-IT看起来很明显,它是在意大利讲意大利语。
同样,pt-PT 看起来很明显是用于葡萄牙葡萄牙语的。不幸的是,情况并非如此。基于某些不确定的原因(可能是人口、原籍国、国家语言等),存在一种全球标准化,该标准化决定了在尝试从区域设置 ID (在这种情况下为pt)创建特定区域设置时所使用的默认区域设置。Microsoft 已在以下链接中记录了整个列表:

http://msdn.microsoft.com/en-us/goglobal/bb896001.aspx

如果您想知道给定文化或语言的默认国家区域设置是哪个,只需匹配上面链接中的最后一列(语言名称缩写)代码。对于葡萄牙语,不变文化的语言名称缩写与“葡萄牙语(巴西)”匹配,即PTB。葡萄牙(葡萄牙)有一个不同的代码PTG。因此,在这种情况下,葡萄牙语(巴西)是葡萄牙语的默认区域设置。如果您的应用程序逻辑或要求以任何方式依赖此API的行为,则必须小心。在基于Web的应用程序中,此行为变得更加重要,因为市场上的所有浏览器也遵循这些指南,并在查看多语言网站的本地化版本时在http请求标头中发送适当的信息。我仍在寻找原因,即在任何文化中将特定国家设置为默认区域设置的因素,这在葡萄牙语的情况下似乎并不明显。欢迎提供任何信息或评论。

感谢分享你的发现。我稍微重构了你的答案,以便更清晰易读。 - Marcel

2
工厂方法和构造函数之间还有一个明显的区别:构造函数提供了一个额外的可选布尔值,其默认值为true。
如果您真正需要一个“普通”的CultureInfo,则需要将此布尔值设置为false,因为: 如果您请求特定的文化(例如de-DE),而没有将“Boolean设置为false”,则始终会获得一个文化设置,该设置可能具有意外的设置,这取决于用户如何通过控制面板更改此文化。
工厂方法不支持此布尔值!!!
当您希望此布尔值为以下两种情况之一时,请考虑以下两点:
1. true:您正在为UI生成输出-此输出应根据用户通过控制面板选择的特定Culture-Settings进行。 2. false:您想解析数据(例如来自XML的数据),并且您知道特定的XML-culture-settings(例如小数分隔符为逗号)。在这种情况下,您将需要一个“纯粹的de-DE”-Culture,以确保特殊的控制面板设置不会干扰。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接