Klasa CultureInfo

Ten artykuł zawiera dodatkowe uwagi dotyczące dokumentacji referencyjnej dla tego interfejsu API.

Klasa CultureInfo udostępnia informacje specyficzne dla kultury, takie jak język, podjęzyczność, kraj/region, kalendarz i konwencje skojarzone z określoną kulturą. Ta klasa zapewnia również dostęp do wystąpień specyficznych DateTimeFormatInfodla kultury obiektów , NumberFormatInfo, CompareInfoi TextInfo . Te obiekty zawierają informacje wymagane dla operacji specyficznych dla kultury, takich jak wielkość liter, formatowanie dat i liczb oraz porównywanie ciągów. Klasa CultureInfo jest używana bezpośrednio lub pośrednio przez klasy, które formatują, analizują lub manipulują danymi specyficznymi dla kultury, takimi jak String, DateTime, DateTimeOffseti typy liczbowe.

Nazwy i identyfikatory kultur

Klasa CultureInfo określa unikatową nazwę każdej kultury na podstawie RFC 4646. Nazwa jest kombinacją dwuliterowego lub trzyliterowego kodu kultury ISO 639 skojarzonego z językiem oraz dwuliterowego kodu subkultury iso 3166 skojarzonego z krajem lub regionem. Ponadto w przypadku aplikacji z systemem Windows 10 lub nowszym obsługiwane są nazwy kultury odpowiadające prawidłowym tagom języka BCP-47.

Uwaga

Gdy nazwa kultury jest przekazywana do konstruktora klasy lub metody, takiej jak CreateSpecificCulture lub CultureInfo, jej przypadek nie jest znaczący.

Format nazwy kultury opartej na specyfikacji RFC 4646 to languagecode2-country/regioncode2, gdzie languagecode2 jest dwuliterowym kodem języka i country/regioncode2 jest dwuliterowym kodem subkultury. Przykłady obejmują ja-JP język japoński (Japonia) i en-US angielski (Stany Zjednoczone). W przypadkach, gdy kod języka dwuliterowego jest niedostępny, używany jest trzyliterowy kod zdefiniowany w standardze ISO 639-3.

Niektóre nazwy kultur określają również skrypt ISO 15924. Na przykład Cyrl określa skrypt cyrylica, a Latn określa skrypt łaciński. Nazwa kultury zawierająca skrypt używa wzorca languagecode2country/regioncode2-scripttag-. Przykładem tej nazwy kultury jest uz-Cyrl-UZ uzbek (cyrylica, Uzbekistan). W systemach operacyjnych Windows przed Windows Vista nazwa kultury zawierająca skrypt używa wzorca languagecode2--country/regioncode2scripttag, na przykład uz-UZ-Cyrl dla Uzbek (Cyrylica, Uzbekistan).

Neutralna kultura jest określana tylko za pomocą dwuliterowego, małego kodu języka. Na przykład fr określa neutralną kulturę języka francuskiego i de określa neutralną kulturę dla języka niemieckiego.

Uwaga

Istnieją dwie nazwy kultury, które są sprzeczne z tą regułą. Kultury chińskie (uproszczone), o nazwach , i chiński (tradycyjny), o nazwie zh-Hanszh-Hant, są kulturami neutralnymi. Nazwy kultury reprezentują bieżący standard i powinny być używane, chyba że masz przyczynę używania starszych nazw zh-CHS i zh-CHT.

Identyfikator kultury jest standardowym międzynarodowym skrótem liczbowym i zawiera składniki niezbędne do unikatowego zidentyfikowania jednej z zainstalowanych kultur. Aplikacja może używać wstępnie zdefiniowanych identyfikatorów kultury lub definiować identyfikatory niestandardowe.

Niektóre wstępnie zdefiniowane nazwy i identyfikatory kultury są używane przez te i inne klasy w System.Globalization przestrzeni nazw. Aby uzyskać szczegółowe informacje o kulturze systemów Windows, zobacz kolumnę Tag języka na liście nazw języków/regionów obsługiwanych przez system Windows. Nazwy kultur są zgodne ze standardem zdefiniowanym przez BCP 47.

Nazwy i identyfikatory kultury reprezentują tylko podzbiór kultur, które można znaleźć na określonym komputerze. Wersje systemu Windows lub dodatki Service Pack mogą zmieniać dostępne kultury. Aplikacje mogą dodawać kultury niestandardowe przy użyciu CultureAndRegionInfoBuilder klasy . Użytkownicy mogą dodawać własne kultury niestandardowe przy użyciu narzędzia Microsoft Locale Builder . Program Microsoft Locale Builder jest napisany w kodzie zarządzanym CultureAndRegionInfoBuilder przy użyciu klasy .

Kilka odrębnych nazw jest ściśle skojarzonych z kulturą, zwłaszcza nazwy skojarzone z następującymi składowymi klasy:

Niezmienne, neutralne i specyficzne kultury

Kultury są zwykle pogrupowane w trzy zestawy: niezmienne kultury, kultury neutralne i określone kultury.

Niezmienna kultura jest niewrażliwa na kulturę. Aplikacja określa niezmienną kulturę przy użyciu pustego ciągu ("") lub jego identyfikatora. InvariantCulture definiuje wystąpienie niezmiennej kultury. Jest on skojarzony z językiem angielskim, ale nie z żadnym krajem/regionem. Jest on używany w prawie każdej metodzie Globalization w przestrzeni nazw, która wymaga kultury.

Neutralna kultura to kultura skojarzona z językiem, ale nie z krajem/regionem. Konkretna kultura to kultura skojarzona z językiem i krajem/regionem. Na przykład fr jest neutralną nazwą kultury francuskiej i fr-FR jest nazwą konkretnej kultury francuskiej (Francji). Należy pamiętać, że chińskie (uproszczone) i chińskie (tradycyjne) są również uważane za neutralne kultury.

Tworzenie wystąpienia CompareInfo klasy dla kultury neutralnej nie jest zalecane, ponieważ dane, które zawiera, są dowolne. Aby wyświetlić i sortować dane, określ język i region. Name Ponadto właściwość obiektu utworzonego CompareInfo dla kultury neutralnej zwraca tylko kraj i nie zawiera regionu.

Zdefiniowane kultury mają hierarchię, w której element nadrzędny określonej kultury jest kulturą neutralną, a element nadrzędny kultury neutralnej jest niezmienną kulturą. Właściwość Parent zawiera kulturę neutralną skojarzona z określoną kulturą. Kultury niestandardowe powinny definiować Parent właściwość zgodnie z tym wzorcem.

Jeśli zasoby dla określonej kultury nie są dostępne w systemie operacyjnym, używane są zasoby skojarzonej kultury neutralnej. Jeśli zasoby dla kultury neutralnej nie są dostępne, używane są zasoby osadzone w zestawie głównym. Aby uzyskać więcej informacji na temat procesu rezerwowego zasobów, zobacz Pakowanie i wdrażanie zasobów.

Lista ustawień regionalnych w interfejsie API systemu Windows różni się nieco od listy kultur obsługiwanych przez platformę .NET. Jeśli wymagane jest współdziałanie z systemem Windows, na przykład za pośrednictwem mechanizmu p/invoke, aplikacja powinna używać określonej kultury zdefiniowanej dla systemu operacyjnego. Użycie określonej kultury zapewnia spójność z równoważnymi ustawieniami regionalnymi systemu Windows, który jest identyfikowany z identyfikatorem ustawień regionalnych, który jest taki sam jak LCID.

Element DateTimeFormatInfo lub NumberFormatInfo można utworzyć tylko dla niezmiennej kultury lub dla określonych kultur, a nie dla kultur neutralnych.

Jeśli DateTimeFormatInfo.Calendar parametr ma TaiwanCalendar wartość , ale Thread.CurrentCulture nie jest ustawiony na zh-TW, , DateTimeFormatInfo.GetEraNameDateTimeFormatInfo.NativeCalendarNamei DateTimeFormatInfo.GetAbbreviatedEraName zwraca pusty ciąg ("").

Kultury niestandardowe

W systemie Windows można tworzyć niestandardowe ustawienia regionalne. Aby uzyskać więcej informacji, zobacz Ustawienia regionalne niestandardowe.

Informacje o kulturze i dane kulturowe

Platforma .NET uzyskuje dane kulturowe z jednego z różnych źródeł, w zależności od implementacji, platformy i wersji:

  • We wszystkich wersjach platformy .NET (Core) działających na platformach Unix lub Windows 10 lub nowszych wersjach dane kulturowe są udostępniane przez bibliotekę International Components for Unicode (ICU). Określona wersja biblioteki ICU zależy od poszczególnych systemów operacyjnych.
  • We wszystkich wersjach platformy .NET (Core) działających w systemie Windows 9 i starszych wersjach dane kulturowe są dostarczane przez system operacyjny Windows.
  • W programie .NET Framework 4 i nowszych wersjach dane kulturowe są dostarczane przez system operacyjny Windows.

W związku z tym kultura dostępna w określonej implementacji, platformie lub wersji platformy .NET może nie być dostępna w innej implementacji, platformie lub wersji platformy .NET.

Niektóre CultureInfo obiekty różnią się w zależności od platformy bazowej. W szczególności , zh-CNlub chiński (uproszczony, Chiny) i zh-TW, lub chiński (tradycyjny, Tajwan), są dostępne kultury w systemach Windows, ale są to kultury aliasów w systemach Unix. "zh-CN" jest aliasem kultury "zh-Hans-CN", a "zh-TW" jest aliasem kultury "zh-Hag-TW". Kultury aliasowe nie są zwracane przez wywołania GetCultures metody i mogą mieć różne wartości właściwości, w tym różne Parent kultury, niż ich odpowiedniki systemu Windows. zh-CN W przypadku kultur i zh-TW te różnice obejmują następujące elementy:

  • W systemach Windows kultura nadrzędna kultury "zh-CN" to "zh-Hans", a kultura nadrzędna kultury "zh-TW" to "zh-Hant". Kultura nadrzędna obu tych kultur to "zh". W systemach Unix elementy nadrzędne obu kultur to "zh". Oznacza to, że jeśli nie udostępniasz zasobów specyficznych dla kultury dla kultur "zh-CN" lub "zh-TW", ale udostępniasz zasoby dla neutralnej kultury "zh-Hans" lub "zh-Unix", aplikacja załaduje zasoby dla neutralnej kultury w systemie Windows, ale nie w systemie Unix. W systemach Unix należy jawnie ustawić wątek CurrentUICulture na "zh-Hans" lub "zh-Mop".

  • W systemach Windows wywołanie CultureInfo.Equals wystąpienia reprezentującego kulturę "zh-CN" i przekazanie jej wystąpienia "zh-Hans-CN" zwraca wartość true. W systemach Unix wywołanie metody zwraca wartość false. To zachowanie dotyczy również wywoływania Equals wystąpienia "zh-TW" CultureInfo i przekazywania go do wystąpienia "zh-Oj-Tw".

Dynamiczne dane kultury

Z wyjątkiem niezmiennej kultury dane kulturowe są dynamiczne. Dotyczy to nawet wstępnie zdefiniowanych kultur. Na przykład kraje lub regiony przyjmują nowe waluty, zmieniają pisownię wyrazów lub zmieniają preferowany kalendarz, a definicje kultury zmieniają się, aby to śledzić. Kultury niestandardowe mogą ulec zmianie bez powiadomienia, a każda konkretna kultura może zostać zastąpiona przez niestandardową kulturę zastępczą. Ponadto, jak opisano poniżej, indywidualny użytkownik może zastąpić preferencje kulturowe. Aplikacje powinny zawsze uzyskiwać dane kulturowe w czasie wykonywania.

Uwaga

Podczas zapisywania danych aplikacja powinna używać niezmiennej kultury, formatu binarnego lub określonego formatu niezależnego od kultury. Dane zapisane zgodnie z bieżącymi wartościami skojarzonymi z konkretną kulturą, inną niż niezmienna kultura, mogą stać się nieczytelne lub mogą ulec zmianie w znaczeniu, jeśli ta kultura ulegnie zmianie.

Bieżąca kultura i bieżąca kultura interfejsu użytkownika

Każdy wątek w aplikacji .NET ma bieżącą kulturę i bieżącą kulturę interfejsu użytkownika. Bieżąca kultura określa konwencje formatowania dat, godzin, liczb i wartości walutowych, kolejność sortowania tekstu, konwencje wielkości liter i sposoby porównywania ciągów. Bieżąca kultura interfejsu użytkownika służy do pobierania zasobów specyficznych dla kultury w czasie wykonywania.

Uwaga

Aby uzyskać informacje na temat sposobu określania bieżącej i bieżącej kultury interfejsu użytkownika na podstawie wątku, zobacz sekcję Kultura i wątki . Aby uzyskać informacje na temat sposobu określania bieżącej i bieżącej kultury interfejsu użytkownika w wątkach wykonywanych w nowej domenie aplikacji oraz wątków, które przekraczają granice domeny aplikacji, zobacz sekcję Kultury i domeny aplikacji. Aby uzyskać informacje na temat sposobu określania bieżącej i bieżącej kultury interfejsu użytkownika w wątkach wykonujących operacje asynchroniczne oparte na zadaniach, zobacz sekcję Kultura i operacje asynchroniczne oparte na zadaniach.

Aby uzyskać bardziej szczegółowe informacje na temat bieżącej kultury, zobacz CultureInfo.CurrentCulture właściwość . Aby uzyskać bardziej szczegółowe informacje na temat bieżącej kultury interfejsu użytkownika, zobacz CultureInfo.CurrentUICulture temat właściwości.

Pobieranie bieżących i bieżących kultur interfejsu użytkownika

Obiekt reprezentujący bieżącą kulturę CultureInfo można uzyskać na jeden z dwóch sposobów:

Poniższy przykład pobiera obie wartości właściwości, porównuje je, aby pokazać, że są równe, i wyświetla nazwę bieżącej kultury.

using System;
using System.Globalization;
using System.Threading;

public class CurrentCultureEx
{
    public static void Main()
    {
        CultureInfo culture1 = CultureInfo.CurrentCulture;
        CultureInfo culture2 = Thread.CurrentThread.CurrentCulture;
        Console.WriteLine("The current culture is {0}", culture1.Name);
        Console.WriteLine("The two CultureInfo objects are equal: {0}",
                          culture1 == culture2);
    }
}
// The example displays output like the following:
//     The current culture is en-US
//     The two CultureInfo objects are equal: True

Obiekt reprezentujący bieżącą kulturę CultureInfo interfejsu użytkownika można uzyskać na jeden z dwóch sposobów:

Poniższy przykład pobiera obie wartości właściwości, porównuje je, aby pokazać, że są równe, i wyświetla nazwę bieżącej kultury interfejsu użytkownika.

using System;
using System.Globalization;
using System.Threading;

public class CurrentUIEx
{
    public static void Main()
    {
        CultureInfo uiCulture1 = CultureInfo.CurrentUICulture;
        CultureInfo uiCulture2 = Thread.CurrentThread.CurrentUICulture;
        Console.WriteLine("The current UI culture is {0}", uiCulture1.Name);
        Console.WriteLine("The two CultureInfo objects are equal: {0}",
                          uiCulture1 == uiCulture2);
    }
}
// The example displays output like the following:
//     The current UI culture is en-US
//     The two CultureInfo objects are equal: True

Ustawianie bieżących i bieżących kultur interfejsu użytkownika

Aby zmienić kulturę i kulturę interfejsu użytkownika wątku, wykonaj następujące czynności:

  1. Utworzenie wystąpienia obiektu reprezentującego tę kulturę CultureInfoCultureInfo przez wywołanie konstruktora klasy i przekazanie jej nazwy kultury. Konstruktor CultureInfo(String) tworzy wystąpienie CultureInfo obiektu, który odzwierciedla przesłonięcia użytkownika, jeśli nowa kultura jest taka sama jak bieżąca kultura systemu Windows. Konstruktor CultureInfo(String, Boolean) umożliwia określenie, czy nowo utworzony CultureInfo obiekt odzwierciedla przesłonięcia użytkownika, jeśli nowa kultura jest taka sama jak bieżąca kultura systemu Windows.

  2. CultureInfo Przypisz obiekt do CultureInfo.CurrentCulture właściwości or CultureInfo.CurrentUICulture na platformach .NET Core i .NET Framework 4.6 i nowszych wersjach.

Poniższy przykład pobiera bieżącą kulturę. Jeśli jest to coś innego niż kultura francuska (Francja), zmienia obecną kulturę na Francuską (Francja). W przeciwnym razie zmienia bieżącą kulturę na francuski (Luksemburg).

using System;
using System.Globalization;

public class ChangeEx1
{
    public static void Main()
    {
        CultureInfo current = CultureInfo.CurrentCulture;
        Console.WriteLine("The current culture is {0}", current.Name);
        CultureInfo newCulture;
        if (current.Name.Equals("fr-FR"))
            newCulture = new CultureInfo("fr-LU");
        else
            newCulture = new CultureInfo("fr-FR");

        CultureInfo.CurrentCulture = newCulture;
        Console.WriteLine("The current culture is now {0}",
                          CultureInfo.CurrentCulture.Name);
    }
}
// The example displays output like the following:
//     The current culture is en-US
//     The current culture is now fr-FR

Poniższy przykład pobiera bieżącą kulturę. Jeśli jest to coś innego słoweńskiej (słowenii), zmienia obecną kulturę na słoweński (Słowenia). W przeciwnym razie zmienia obecną kulturę na Chorwacką (Chorwacja).

using System;
using System.Globalization;

public class ChangeUICultureEx
{
    public static void Main()
    {
        CultureInfo current = CultureInfo.CurrentUICulture;
        Console.WriteLine("The current UI culture is {0}", current.Name);
        CultureInfo newUICulture;
        if (current.Name.Equals("sl-SI"))
            newUICulture = new CultureInfo("hr-HR");
        else
            newUICulture = new CultureInfo("sl-SI");

        CultureInfo.CurrentUICulture = newUICulture;
        Console.WriteLine("The current UI culture is now {0}",
                          CultureInfo.CurrentUICulture.Name);
    }
}
// The example displays output like the following:
//     The current UI culture is en-US
//     The current UI culture is now sl-SI

Pobieranie wszystkich kultur

Można pobrać tablicę określonych kategorii kultur lub wszystkich kultur dostępnych na komputerze lokalnym, wywołując metodę GetCultures . Można na przykład pobrać kultury niestandardowe, określone kultury lub kultury neutralne albo same lub w połączeniu.

Poniższy przykład wywołuje metodę GetCultures dwa razy, najpierw z elementem System.Globalization.CultureTypes członkowskim wyliczenia w celu pobrania wszystkich kultur niestandardowych, a następnie z System.Globalization.CultureTypes elementem członkowskim wyliczenia w celu pobrania wszystkich kultur zastępczych.

using System;
using System.Globalization;

public class GetCulturesEx
{
    public static void Main()
    {
        // Get all custom cultures.
        CultureInfo[] custom = CultureInfo.GetCultures(CultureTypes.UserCustomCulture);
        if (custom.Length == 0)
        {
            Console.WriteLine("There are no user-defined custom cultures.");
        }
        else
        {
            Console.WriteLine("Custom cultures:");
            foreach (var culture in custom)
                Console.WriteLine("   {0} -- {1}", culture.Name, culture.DisplayName);
        }
        Console.WriteLine();

        // Get all replacement cultures.
        CultureInfo[] replacements = CultureInfo.GetCultures(CultureTypes.ReplacementCultures);
        if (replacements.Length == 0)
        {
            Console.WriteLine("There are no replacement cultures.");
        }
        else
        {
            Console.WriteLine("Replacement cultures:");
            foreach (var culture in replacements)
                Console.WriteLine("   {0} -- {1}", culture.Name, culture.DisplayName);
        }
        Console.WriteLine();
    }
}
// The example displays output like the following:
//     Custom cultures:
//        x-en-US-sample -- English (United States)
//        fj-FJ -- Boumaa Fijian (Viti)
//
//     There are no replacement cultures.

Kultura i wątki

Po uruchomieniu nowego wątku aplikacji bieżąca kultura i bieżąca kultura interfejsu użytkownika są definiowane przez bieżącą kulturę systemu, a nie przez bieżącą kulturę wątków. Poniższy przykład ilustruje różnicę. Ustawia bieżącą kulturę i bieżącą kulturę interfejsu użytkownika wątku aplikacji na kulturę francuską (Francja) (fr-FR). Jeśli bieżąca kultura jest już fr-FR, przykład ustawia ją na kulturę angielską (Stany Zjednoczone) (en-US). Wyświetla trzy losowe liczby jako wartości waluty, a następnie tworzy nowy wątek, który z kolei wyświetla trzy kolejne losowe liczby jako wartości waluty. Jednak jak pokazuje dane wyjściowe z przykładu, wartości walut wyświetlane przez nowy wątek nie odzwierciedlają konwencji formatowania kultury francuskiej (Francji), w przeciwieństwie do danych wyjściowych głównego wątku aplikacji.

using System;
using System.Globalization;
using System.Threading;

public class DefaultThreadEx
{
    static Random rnd = new Random();

    public static void Main()
    {
        if (Thread.CurrentThread.CurrentCulture.Name != "fr-FR")
        {
            // If current culture is not fr-FR, set culture to fr-FR.
            Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture("fr-FR");
            Thread.CurrentThread.CurrentUICulture = CultureInfo.CreateSpecificCulture("fr-FR");
        }
        else
        {
            // Set culture to en-US.
            Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture("en-US");
            Thread.CurrentThread.CurrentUICulture = CultureInfo.CreateSpecificCulture("en-US");
        }
        ThreadProc();

        Thread worker = new Thread(ThreadProc);
        worker.Name = "WorkerThread";
        worker.Start();
    }

    private static void DisplayThreadInfo()
    {
        Console.WriteLine("\nCurrent Thread Name: '{0}'",
                          Thread.CurrentThread.Name);
        Console.WriteLine("Current Thread Culture/UI Culture: {0}/{1}",
                          Thread.CurrentThread.CurrentCulture.Name,
                          Thread.CurrentThread.CurrentUICulture.Name);
    }

    private static void DisplayValues()
    {
        // Create new thread and display three random numbers.
        Console.WriteLine("Some currency values:");
        for (int ctr = 0; ctr <= 3; ctr++)
            Console.WriteLine("   {0:C2}", rnd.NextDouble() * 10);
    }

    private static void ThreadProc()
    {
        DisplayThreadInfo();
        DisplayValues();
    }
}
// The example displays output similar to the following:
//       Current Thread Name: ''
//       Current Thread Culture/UI Culture: fr-FR/fr-FR
//       Some currency values:
//          8,11 €
//          1,48 €
//          8,99 €
//          9,04 €
//
//       Current Thread Name: 'WorkerThread'
//       Current Thread Culture/UI Culture: en-US/en-US
//       Some currency values:
//          $6.72
//          $6.35
//          $2.90
//          $7.72

Kulturę i kulturę interfejsu użytkownika wszystkich wątków w domenie aplikacji można ustawić, przypisując obiekt reprezentujący ten kulturę CultureInfo do DefaultThreadCurrentCulture właściwości i DefaultThreadCurrentUICulture . W poniższym przykładzie użyto tych właściwości, aby upewnić się, że wszystkie wątki w domyślnej domenie aplikacji mają taką samą kulturę.

using System;
using System.Globalization;
using System.Threading;

public class SetThreadsEx
{
    static Random rnd = new Random();

    public static void Main()
    {
        if (Thread.CurrentThread.CurrentCulture.Name != "fr-FR")
        {
            // If current culture is not fr-FR, set culture to fr-FR.
            CultureInfo.DefaultThreadCurrentCulture = CultureInfo.CreateSpecificCulture("fr-FR");
            CultureInfo.DefaultThreadCurrentUICulture = CultureInfo.CreateSpecificCulture("fr-FR");
        }
        else
        {
            // Set culture to en-US.
            CultureInfo.DefaultThreadCurrentCulture = CultureInfo.CreateSpecificCulture("en-US");
            CultureInfo.DefaultThreadCurrentUICulture = CultureInfo.CreateSpecificCulture("en-US");
        }
        ThreadProc();

        Thread worker = new Thread(SetThreadsEx.ThreadProc);
        worker.Name = "WorkerThread";
        worker.Start();
    }

    private static void DisplayThreadInfo()
    {
        Console.WriteLine("\nCurrent Thread Name: '{0}'",
                          Thread.CurrentThread.Name);
        Console.WriteLine("Current Thread Culture/UI Culture: {0}/{1}",
                          Thread.CurrentThread.CurrentCulture.Name,
                          Thread.CurrentThread.CurrentUICulture.Name);
    }

    private static void DisplayValues()
    {
        // Create new thread and display three random numbers.
        Console.WriteLine("Some currency values:");
        for (int ctr = 0; ctr <= 3; ctr++)
            Console.WriteLine("   {0:C2}", rnd.NextDouble() * 10);
    }

    private static void ThreadProc()
    {
        DisplayThreadInfo();
        DisplayValues();
    }
}
// The example displays output similar to the following:
//       Current Thread Name: ''
//       Current Thread Culture/UI Culture: fr-FR/fr-FR
//       Some currency values:
//          6,83 €
//          3,47 €
//          6,07 €
//          1,70 €
//
//       Current Thread Name: 'WorkerThread'
//       Current Thread Culture/UI Culture: fr-FR/fr-FR
//       Some currency values:
//          9,54 €
//          9,50 €
//          0,58 €
//          6,91 €

Ostrzeżenie

DefaultThreadCurrentCulture Chociaż właściwości i DefaultThreadCurrentUICulture są statyczne, definiują domyślną kulturę i domyślną kulturę interfejsu użytkownika tylko dla domeny aplikacji, która jest bieżąca w momencie ustawiania tych wartości właściwości. Aby uzyskać więcej informacji, zobacz następną sekcję, Kulturę i domeny aplikacji.

Podczas przypisywania wartości do DefaultThreadCurrentCulture właściwości i DefaultThreadCurrentUICulture kultura kultury i interfejsu użytkownika wątków w domenie aplikacji również zmienia się, jeśli nie zostały jawnie przypisane kultury. Jednak te wątki odzwierciedlają nowe ustawienia kultury tylko podczas wykonywania w bieżącej domenie aplikacji. Jeśli te wątki są wykonywane w innej domenie aplikacji, ich kultura stanie się domyślną kulturą zdefiniowaną dla tej domeny aplikacji. W związku z tym zalecamy, aby zawsze ustawiać kulturę głównego wątku aplikacji, a nie polegać na właściwościach DefaultThreadCurrentCulture i DefaultThreadCurrentUICulture , aby je zmienić.

Kultury i domeny aplikacji

DefaultThreadCurrentCulture i DefaultThreadCurrentUICulture są właściwościami statycznymi, które jawnie definiują kulturę domyślną tylko dla domeny aplikacji, która jest bieżąca, gdy wartość właściwości jest ustawiona lub pobrana. Poniższy przykład ustawia domyślną kulturę i domyślną kulturę interfejsu użytkownika w domyślnej domenie aplikacji na francuski (Francja), a następnie używa AppDomainSetup klasy i delegata AppDomainInitializer , aby ustawić domyślną kulturę i kulturę interfejsu użytkownika w nowej domenie aplikacji na rosyjski (Rosja). Następnie pojedynczy wątek wykonuje dwie metody w każdej domenie aplikacji. Należy pamiętać, że kultura wątku i kultura interfejsu użytkownika nie są jawnie ustawione; pochodzą one z domyślnej kultury i kultury interfejsu użytkownika domeny aplikacji, w której jest wykonywany wątek. Należy również pamiętać, że DefaultThreadCurrentCulture właściwości i DefaultThreadCurrentUICulture zwracają wartości domyślne CultureInfo domeny aplikacji, która jest bieżąca po wywołaniu metody.

using System;
using System.Globalization;

public class Example
{
    public static void Main()
    {
        // Set the default culture and display the current date in the current application domain.
        Info info1 = new Info();
        SetAppDomainCultures("fr-FR");

        // Create a second application domain.
        AppDomainSetup setup = new AppDomainSetup();
        setup.AppDomainInitializer = SetAppDomainCultures;
        setup.AppDomainInitializerArguments = new string[] { "ru-RU" };
        AppDomain domain = AppDomain.CreateDomain("Domain2", null, setup);
        // Create an Info object in the new application domain.
        Info info2 = (Info)domain.CreateInstanceAndUnwrap(typeof(Example).Assembly.FullName,
                                                           "Info");

        // Execute methods in the two application domains.
        info2.DisplayDate();
        info2.DisplayCultures();

        info1.DisplayDate();
        info1.DisplayCultures();
    }

    public static void SetAppDomainCultures(string[] names)
    {
        SetAppDomainCultures(names[0]);
    }

    public static void SetAppDomainCultures(string name)
    {
        try
        {
            CultureInfo.DefaultThreadCurrentCulture = CultureInfo.CreateSpecificCulture(name);
            CultureInfo.DefaultThreadCurrentUICulture = CultureInfo.CreateSpecificCulture(name);
        }
        // If an exception occurs, we'll just fall back to the system default.
        catch (CultureNotFoundException)
        {
            return;
        }
        catch (ArgumentException)
        {
            return;
        }
    }
}

public class Info : MarshalByRefObject
{
    public void DisplayDate()
    {
        Console.WriteLine("Today is {0:D}", DateTime.Now);
    }

    public void DisplayCultures()
    {
        Console.WriteLine("Application domain is {0}", AppDomain.CurrentDomain.Id);
        Console.WriteLine("Default Culture: {0}", CultureInfo.DefaultThreadCurrentCulture);
        Console.WriteLine("Default UI Culture: {0}", CultureInfo.DefaultThreadCurrentUICulture);
    }
}
// The example displays the following output:
//       Today is 14 октября 2011 г.
//       Application domain is 2
//       Default Culture: ru-RU
//       Default UI Culture: ru-RU
//       Today is vendredi 14 octobre 2011
//       Application domain is 1
//       Default Culture: fr-FR
//       Default UI Culture: fr-FR

Aby uzyskać więcej informacji na temat kultur i domen aplikacji, zobacz sekcję "Domeny aplikacji i wątki" w temacie Domeny aplikacji.

Operacje asynchroniczne oparte na kulturze i zadaniach

Wzorzec programowania asynchronicznego oparty na zadaniach używa obiektów Task i Task<TResult> do asynchronicznego wykonywania delegatów w wątkach puli wątków. Określony wątek, na którym jest uruchamiane określone zadanie, nie jest znany z wyprzedzeniem, ale jest określany tylko w czasie wykonywania.

W przypadku aplikacji przeznaczonych dla programu .NET Framework 4.6 lub nowszej wersji kultura jest częścią kontekstu operacji asynchronicznej. Innymi słowy, operacje asynchroniczne domyślnie dziedziczą wartości CurrentCulture właściwości i CurrentUICulture wątku, z którego są uruchamiane. Jeśli bieżąca kultura lub bieżąca kultura interfejsu użytkownika różni się od kultury systemu, bieżąca kultura przekracza granice wątków i staje się bieżącą kulturą wątku wątku, który wykonuje operację asynchroniczną.

Poniższy przykład przedstawia prostą ilustrację. W przykładzie zdefiniowano delegata Func<TResult> , formatDelegatektóry zwraca niektóre liczby sformatowane jako wartości waluty. Przykład zmienia bieżącą kulturę systemu na francuski (Francja) lub, jeśli francuski (Francja) jest już bieżącą kulturą, angielski (Stany Zjednoczone). W ten sposób:

  • Wywołuje delegata bezpośrednio, aby był uruchamiany synchronicznie w głównym wątku aplikacji.
  • Tworzy zadanie, które wykonuje delegat asynchronicznie w wątku puli wątków.
  • Tworzy zadanie, które wykonuje delegat synchronicznie w głównym wątku aplikacji, wywołując metodę Task.RunSynchronously .

Jak pokazuje dane wyjściowe z przykładu, gdy bieżąca kultura zostanie zmieniona na francuską (Francja), bieżącą kulturę wątku, z którego zadania są wywoływane asynchronicznie, staje się bieżącą kulturą dla tej operacji asynchronicznej.

using System;
using System.Globalization;
using System.Threading;
using System.Threading.Tasks;

public class AsyncCultureEx1
{
    public static void Main()
    {
        decimal[] values = { 163025412.32m, 18905365.59m };
        string formatString = "C2";

        string FormatDelegate()
        {
            string output = $"Formatting using the {CultureInfo.CurrentCulture.Name} " +
            "culture on thread {Thread.CurrentThread.ManagedThreadId}.\n";
            foreach (decimal value in values)
                output += $"{value.ToString(formatString)}   ";

            output += Environment.NewLine;
            return output;
        }

        Console.WriteLine($"The example is running on thread {Thread.CurrentThread.ManagedThreadId}");
        // Make the current culture different from the system culture.
        Console.WriteLine($"The current culture is {CultureInfo.CurrentCulture.Name}");
        if (CultureInfo.CurrentCulture.Name == "fr-FR")
            Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");
        else
            Thread.CurrentThread.CurrentCulture = new CultureInfo("fr-FR");

        Console.WriteLine($"Changed the current culture to {CultureInfo.CurrentCulture.Name}.\n");

        // Execute the delegate synchronously.
        Console.WriteLine("Executing the delegate synchronously:");
        Console.WriteLine(FormatDelegate());

        // Call an async delegate to format the values using one format string.
        Console.WriteLine("Executing a task asynchronously:");
        var t1 = Task.Run(FormatDelegate);
        Console.WriteLine(t1.Result);

        Console.WriteLine("Executing a task synchronously:");
        var t2 = new Task<string>(FormatDelegate);
        t2.RunSynchronously();
        Console.WriteLine(t2.Result);
    }
}
// The example displays the following output:
//         The example is running on thread 1
//         The current culture is en-US
//         Changed the current culture to fr-FR.
//
//         Executing the delegate synchronously:
//         Formatting using the fr-FR culture on thread 1.
//         163 025 412,32 €   18 905 365,59 €
//
//         Executing a task asynchronously:
//         Formatting using the fr-FR culture on thread 3.
//         163 025 412,32 €   18 905 365,59 €
//
//         Executing a task synchronously:
//         Formatting using the fr-FR culture on thread 1.
//         163 025 412,32 €   18 905 365,59 €

DefaultThreadCurrentCulture i DefaultThreadCurrentUICulture są właściwościami domeny dla aplikacji. Oznacza to, że ustanawiają domyślną kulturę dla wszystkich wątków, które nie zostały jawnie przypisane do kultury w określonej domenie aplikacji. Jednak w przypadku aplikacji przeznaczonych dla platformy .NET Framework 4.6 lub nowszej kultura wątku wywołującego pozostaje częścią kontekstu zadania asynchronicznego, nawet jeśli zadanie przekracza granice domeny aplikacji.

Serializacja obiektów CultureInfo

CultureInfo Gdy obiekt jest serializowany, wszystko, co jest rzeczywiście przechowywane, to Name i UseUserOverride. Jest ona pomyślnie deserializacji tylko w środowisku, w którym ma to Name samo znaczenie. W poniższych trzech przykładach pokazano, dlaczego tak nie jest zawsze:

  • CultureTypes Jeśli wartość właściwości to CultureTypes.InstalledWin32Cultures, a jeśli ta kultura została po raz pierwszy wprowadzona w określonej wersji systemu operacyjnego Windows, nie można wykonać deserializacji jej we wcześniejszej wersji systemu Windows. Jeśli na przykład w systemie Windows 10 wprowadzono kulturę, nie można jej deserializować w systemie Windows 8.

  • CultureTypes Jeśli wartość to CultureTypes.UserCustomCulture, a komputer, na którym jest deserializowany, nie ma zainstalowanej tej kultury niestandardowej użytkownika, nie można go wykonać deserializacji.

  • CultureTypes Jeśli wartość to CultureTypes.ReplacementCultures, a komputer, na którym jest deserializowany, nie ma tej kultury zastępczej, deserializuje tę samą nazwę, ale nie wszystkie te same cechy. Jeśli na przykład en-US jest kulturą zastępczą na komputerze A, ale nie na komputerze B, a CultureInfo obiekt odwołujący się do tej kultury jest serializowany na komputerze A i deserializowany na komputerze B, żadne z niestandardowych cech kultury nie są przesyłane. Deserializuje kulturę pomyślnie, ale z innym znaczeniem.

Panel sterowania przesłonięcia

Użytkownik może wybrać do nadpisania niektóre wartości skojarzone z bieżącą kulturą systemu Windows korzystając z opcji ustawień regionalnych i językowych w panelu sterowania. Na przykład, użytkownik może wybrać do wyświetlania datę w innym formacie lub użyć waluty innej niż domyślna dla danej kultury. Ogólnie rzecz biorąc, aplikacje powinny przestrzegać tych przesłonięć użytkowników.

Jeśli UseUserOverride jest true i określona kultura jest zgodna z bieżącą kulturą systemu Windows, CultureInfo używa tych przesłonięć, w tym ustawień użytkownika dla właściwości DateTimeFormatInfo wystąpienia zwróconych przez DateTimeFormat właściwość, oraz właściwości NumberFormatInfo wystąpienia zwróconego przez NumberFormat właściwość. Jeśli ustawienia użytkownika są niezgodne z kulturą skojarzoną z elementem , na przykład jeśli wybrany kalendarz nie jest jednym z CultureInfoOptionalCalendarselementów , wyniki metod i wartości właściwości są niezdefiniowane.

Alternatywne zamówienia sortowania

Niektóre kultury obsługują więcej niż jedną kolejność sortowania. Na przykład:

  • Kultura hiszpańska (Hiszpania) ma dwa zamówienia sortowania: domyślną międzynarodową kolejność sortowania i tradycyjną kolejność sortowania. Podczas tworzenia wystąpienia CultureInfo obiektu o es-ES nazwie kultury używany jest międzynarodowy porządek sortowania. Podczas tworzenia wystąpienia CultureInfo obiektu o es-ES-tradnl nazwie kultury jest używana tradycyjna kolejność sortowania.

  • Kultura zh-CN (chiński (uproszczony, CHRL)) obsługuje dwie kolejności sortowania: przez wymowę (domyślną) i według liczby pociągnięć. Podczas tworzenia wystąpienia CultureInfo obiektu o zh-CN nazwie kultury jest używana domyślna kolejność sortowania. Podczas tworzenia wystąpienia CultureInfo obiektu przy użyciu lokalnego identyfikatora 0x00020804 ciągi są sortowane według liczby pociągnięć.

W poniższej tabeli wymieniono kultury, które obsługują alternatywne kolejność sortowania oraz identyfikatory domyślnych i alternatywnych kolejności sortowania.

Nazwa kultury Kultura Domyślna nazwa i identyfikator sortowania Alternatywna nazwa i identyfikator sortowania
es-ES Hiszpański (Hiszpania) Międzynarodowy: 0x00000C0A Tradycyjny: 0x0000040A
zh-TW Chiński (Tajwan) Liczba pociągnięć: 0x00000404 Bopomofo: 0x00030404
zh-CN Chiński (CHRL) Wymowa: 0x00000804 Liczba pociągnięć: 0x00020804
zh-HK Chiński (Hongkong SAR) Liczba pociągnięć: 0x00000c04 Liczba pociągnięć: 0x00020c04
zh-SG Chiński (Singapur) Wymowa: 0x00001004 Liczba pociągnięć: 0x00021004
zh-MO Chiński (Makao SAR) Wymowa: 0x00001404 Liczba pociągnięć: 0x00021404
ja-JP Japoński (Japonia) Ustawienie domyślne: 0x00000411 Unicode: 0x00010411
ko-KR Koreański (Korea) Ustawienie domyślne: 0x00000412 Koreański Xwansung — Unicode: 0x00010412
de-DE Niemiecki (Niemcy) Słownik: 0x00000407 Telefon Book Sort DIN: 0x00010407
hu-HU Węgierski (Węgry) Ustawienie domyślne: 0x0000040e Sortowanie techniczne: 0x0001040e
ka-GE Gruziński (Gruzja) Tradycyjny: 0x00000437 Nowoczesne sortowanie: 0x00010437

Bieżąca kultura i aplikacje platformy UWP

W aplikacjach CurrentCulture platformy platforma uniwersalna systemu Windows (UWP) właściwości i CurrentUICulture są do odczytu i zapisu, podobnie jak w aplikacjach .NET Framework i .NET Core. Jednak aplikacje platformy UNIWERSALNEJ systemu Windows rozpoznają jedną kulturę. Właściwości CurrentCulture i CurrentUICulture mapują na pierwszą wartość w kolekcji Windows.ApplicationModel.Resources.Core.ResourceManager.DefaultContext.Languages .

W aplikacjach platformy .NET bieżąca kultura jest ustawieniem dla wątku, a CurrentCulture właściwości i CurrentUICulture odzwierciedlają kulturę i kulturę interfejsu użytkownika tylko bieżącego wątku. W aplikacjach platformy UWP bieżąca kultura jest mapowana na kolekcję Windows.ApplicationModel.Resources.Core.ResourceManager.DefaultContext.Languages , która jest ustawieniem globalnym. CurrentCulture Ustawienie właściwości or CurrentUICulture zmienia kulturę całej aplikacji; nie można ustawić kultury dla każdego wątku.