Search code examples
c#.netlocalizationinternationalizationcultureinfo

Obtain a language name in different languages


I have the following:

if (currentUICulture.Equals(CultureInfo.GetCultureInfo("fr-FR")))
    _EnglishLabel = "Anglais";
else
    _EnglishLabel = "English";

ask myself if this code can be optimized for an arbitrary number of current cultures.

I could try to get that for the current UI culture, like this:

_EnglishLabel = new CultureInfo("en-US").DisplayName;

but what if I should give the English language not by the currentUICulture, but an arbitrary culture passed as parameter...

in other words, how to get the

new CultureInfo("en-US").GetDisplayName(myArbitraryCulture);

PS.

The .NET Framework code

////////////////////////////////////////////////////////////////////////
//
//  DisplayName
//
//  Returns the full name of the CultureInfo in the localized language.
//  For example, if the localized language of the runtime is Spanish and the CultureInfo is
//  US English, "Ingles (Estados Unidos)" will be returned.
//
////////////////////////////////////////////////////////////////////////
public virtual String DisplayName
{
    [System.Security.SecuritySafeCritical]  // auto-generated
    get
    {
        Contract.Ensures(Contract.Result<String>() != null);
        Contract.Assert(m_name != null, "[CultureInfo.DisplayName]Always expect m_name to be set");

        return m_cultureData.SLOCALIZEDDISPLAYNAME;
    }
}

////////////////////////////////////////////////////////////////////////
//
//  GetNativeName
//
//  Returns the full name of the CultureInfo in the native language.
//  For example, if the CultureInfo is US English, "English
//  (United States)" will be returned.
//
////////////////////////////////////////////////////////////////////////
public virtual String NativeName {
    [System.Security.SecuritySafeCritical]  // auto-generated
    get {
        Contract.Ensures(Contract.Result<String>() != null);
        return (this.m_cultureData.SNATIVEDISPLAYNAME);
    }
}

Solution

  • It is possible to retrieve translations for installed framework languages. The workings are undocumented but the internal implementations can be seen in the reference source (e.g. for CultureData). For target cultures other than installed ones, the English fallback will be returned.

    Building on top of that we can use the following (again, for installed framework languages only):

    public static string GetDisplayName(this CultureInfo culture, CultureInfo locale)
    {
        var rm = new ResourceManager("mscorlib", typeof(object).Assembly);
        var resourceKey = $"Globalization.ci_{culture.Name}";
        return rm.GetString(resourceKey, locale);
    }
    

    For example with Swedish and English installed:

    var culture = CultureInfo.GetCultureInfo("en");
    var swedishName = culture.GetDisplayName(CultureInfo.GetCultureInfo("sv")); // Engelska
    var englishName = culture.GetDisplayName(CultureInfo.GetCultureInfo("en")); // English
    var germanName = culture.GetDisplayName(CultureInfo.GetCultureInfo("de")); // English <- German not installed
    

    To cover all languages (or an arbitrary collection of languages), I would suggest a non-native approach as the built-in way is not really supporting your use case.

    Cheers!