Difference between CultureInfo.CreateSpecificCulture() and the constructor of the class?
Asked Answered
W

3

41

The class CultureInfo provides two way of creation:

The MSDN documentation does slightly differ for the two, mentioning some "Windows culture" for the constructor. But does that really matter?

Should I prefer one of the two over the other?

Note: I am using .NET version 3.5 if that matters, and I want to use it like this:

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

as described in this answer.

Whitefaced answered 30/8, 2012 at 9:35 Comment(0)
C
34

The factory method has an fallback when it fails to create the culture info.

So if you use a specific culture like 'en-XX', the culture info instance can't be created, an exception will throw and a retry with the neutral culture 'en' will succeed.

Below the source of the factory method

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);
}

So the I prefer the factory method.

Cleavers answered 30/8, 2012 at 9:43 Comment(5)
You are right, the factory method can handle that, as my own test shows. However, the fallback only works for the regional part, faulty neutral cultures are not handled by any of the two.Whitefaced
I now use the factory method as suggested. I have unit tested all relevant cultures and it works.Whitefaced
I have noted that for CreateSpecificCulture("en") returns en-us, while new CultureInfo("en") seems to return an invariant EnglishPoulin
@DirkBoer is right. This answer does not cover the fact that there are two kinds of cultures, neutral cultures (like en) and specific cultures (like en-US or en-GB or en-AU). Check the property IsNeutralCulture to find out. And note in the quoted source code of this answer that after the try-catch structure, we check if it is a neutral culture, and if that is the case we create another culture which is specific, from the internal property SSPECIFICCULTURE on an internal member field. See my post elsewhere for examples.Bilander
Therefore, use new CultureInfo(culture) if you want either a neutral or a specific culture (including the special "invariant culture") depending on the string argument. And use CultureInfo.CreateSpecificCulture(culture) if you want to avoid neutral cultures.Bilander
P
7

This thread has alredy been answered but I came across a unique finding for CreateSpecificCulture API which might not be so obvious at times. So I considered this thread to be an apt place for my findings. I spent a few days on this so just thought of sharing my experience if it can save few hours or days for others as well.

While using the API when you pass it only the culture name like pt (for portuguese) or de (for German) this API returns a specific culture corresponding to the locale which is termed as default locale for that culture. Now this locale might not be so obvious as it sounds where I got stuck. For German, de-DE looks obvious which is German spoken in Germany. For Italian, it-IT looks obvious which is Italian spoken in Italy.

Likewise pt-PT looks obvious for Portuguese spoken in Portugal. Unfortunately this is not the case. Based on not sure what exact reason (may be population, country of origin, national language etc.) there is a global standardization based on which the default locale for a given culture is decided when you try to create a specific culture from a culture id (pt in this case). Microsoft has documented the entire list at following link :

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

If you want to know which is the default country locale for a given culture or language just match the last column (Language Name Abbreviation) code in the above link.

For portuguese, the language name abbrevitaion of invariant culture "Portuguese" matches with "Portuguese (Brazil)" which is PTB. Portuguese(Portugal) has a different code PTG. So in this case Portuguese (Brazil) is the default locale for portuguese language.

If your application logic or requirements are in any way relying on this behavior of this API you got to be cautious. This behavior becomes more important in web based applications as all browsers in the market also follow these guidelines and send appropriate information in the http request header when you are looking at a localised version of a multi lingual website.

I'm still looking for the reason though which is THE factor behind setting a specific country as default locale for any culture which doesn't sound so obvious in case of Portuguese. Any information or comments are welcome.

Panegyrize answered 21/10, 2014 at 7:28 Comment(1)
Thanks for sharing your findings. I restructured your answer a bit for more clarity and ease of reading.Whitefaced
C
2

There is another noticable difference between the factory-method and the contructor: The constructor offers an additional optional boolean, which has its default set to true.

You will need this Boolean to be set to false, if you really need a >"plain"< cultureinfo, because: If you're requesting a specific culture (e.g. de-DE) without "Boolean set to false" you will always get a culture-setting, which could have unexpected settings, depending on how the user has changed this culture via Control-Panel.

The factory-method does not support this Boolean !!!

Just two final thoughts on when you want this boolean to be:

  • true: You are generating ouput for you UI - This Output should be according to the specific Culture-Settings, which the user has chosen via Control-Panel
  • false: You want to parse data (e.g. from XML) and you know the specific XML-culture-settings (e.g. decimal-separator as comma). In this case you will need a plain de-DE - Culture for being sure, that special control-panel-setting would not interfere.
Carbolize answered 28/3, 2017 at 11:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.