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

Posted

技术标签:

【中文标题】CultureInfo.CreateSpecificCulture() 和类的构造函数之间的区别?【英文标题】:Difference between CultureInfo.CreateSpecificCulture() and the constructor of the class? 【发布时间】:2012-08-25 00:09:39 【问题描述】:

CultureInfo 类提供了两种创建方式:

通过factory method CreateSpecificCulture(string)。 通过constructor with a string argument

两者的 MSDN 文档确实略有不同,其中提到了构造函数的一些“Windows 文化”。但这真的重要吗?

我应该更喜欢两者中的一个吗?

注意:如果这很重要,我正在使用 .NET 3.5 版,我想这样使用它:

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

作为described in this answer.

【问题讨论】:

【参考方案1】:

工厂方法在创建文化信息失败时有一个回退。

因此,如果您使用“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);

所以我更喜欢工厂方法。

【讨论】:

你是对的,工厂方法可以处理这个问题,正如我自己的测试所示。但是,后备只适用于区域部分,有缺陷的中立文化不会由两者中的任何一个处理。 我现在按照建议使用工厂方法。我已经对所有相关文化进行了单元测试,并且效果很好。 我注意到 CreateSpecificCulture("en") 返回 en-us,而 new CultureInfo("en") 似乎返回不变的英语 @DirkBoer 是对的。这个答案不包括有两种文化,中性文化(如en)和特定文化(如en-USen-GBen-AU)。检查属性IsNeutralCulture 以找出答案。并在此答案的引用源代码中注意,在 try-catch 结构之后,我们检查它是否是中性文化,如果是这种情况,我们创建 another 文化,即具体来说,来自内部成员字段上的internal 属性SSPECIFICCULTURE。有关示例,请参阅my post elsewhere。 因此,如果您想要中性或特定文化(包括特殊的“不变文化”),请使用new CultureInfo(culture),具体取决于字符串参数。如果您想避免中立文化,请使用CultureInfo.CreateSpecificCulture(culture)【参考方案2】:

这个帖子已经得到了回答,但我发现了一个关于 CreateSpecificCulture API 的独特发现,它有时可能不那么明显。所以我认为这个线程是我发现的一个合适的地方。我花了几天时间,所以只想分享我的经验,如果它也可以为其他人节省几个小时或几天。

当您使用 API 时,仅传递文化名称,如 pt(葡萄牙语)或 de(德语),此 API 返回与区域设置相对应的特定文化,该区域被称为该区域的默认区域设置.现在这个语言环境可能不像听起来我卡住的地方那么明显。对于德语,de-DE 看起来很明显,这是在德国说的德语。对于意大利语,it-IT 看起来很明显,这是在意大利说的意大利语。

同样,pt-PT 对于在葡萄牙说的葡萄牙语来说很明显。不幸的是,不是的情况。基于不确定的确切原因(可能是人口、原籍国、国家语言等),有一个全球标准化,当您尝试从文化 id 创建特定文化时,根据该标准确定给定文化的默认区域设置(在这种情况下为pt)。 Microsoft 在以下链接中记录了整个列表:

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

如果您想知道给定文化或语言的默认国家/地区区域设置,只需匹配上述链接中的最后一列(语言名称缩写)代码即可。

对于葡萄牙语,固定文化“葡萄牙语”的语言名称缩写与“葡萄牙语(巴西)”相匹配,即 PTB。葡萄牙语(葡萄牙)有不同的代码PTG。所以在这种情况下,葡萄牙语(巴西)是葡萄牙语的默认语言环境。

如果您的应用程序逻辑或要求以任何方式依赖于此 API 的这种行为,您必须谨慎。这种行为在基于 Web 的应用程序中变得更加重要,因为市场上的所有浏览器也都遵循这些准则,并在您查看多语言网站的本地化版本时在 http 请求标头中发送适当的信息。

我仍在寻找原因,但 将特定国家/地区设置为任何文化的默认语言环境,这在葡萄牙语的情况下听起来并不那么明显。欢迎任何信息或cmets。

【讨论】:

感谢您分享您的发现。为了更清晰和易于阅读,我对您的答案进行了一些调整。【参考方案3】:

工厂方法和构造函数之间还有一个明显的区别:构造函数提供了一个额外的可选布尔值,它的默认设置为 true。

如果您确实需要 >"plain"de-DE)而没有“布尔设置为false”,您将始终得到一个文化设置,它可能有意想不到的设置,具体取决于用户如何通过控制面板更改此文化。

工厂方法不支持这个布尔值!!!

关于你希望这个布尔值何时成为的最后两个想法:

true:您正在为您的 UI 生成输出 - 此输出应根据用户通过控制面板选择的特定文化设置 false:您想要解析数据(例如,来自 XML)并且您知道特定的 XML 文化设置(例如,十进制分隔符为逗号)。在这种情况下,您将需要 plain de-DE - 文化可以肯定,特殊的控制面板设置不会干扰。

【讨论】:

以上是关于CultureInfo.CreateSpecificCulture() 和类的构造函数之间的区别?的主要内容,如果未能解决你的问题,请参考以下文章