Uwaga
Dostęp do tej strony wymaga autoryzacji. Może spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
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 specyficznych dla kultury wystąpień obiektów DateTimeFormatInfo, NumberFormatInfo, CompareInfo i TextInfo. Te obiekty zawierają informacje wymagane do operacji specyficznych dla poszczególnych kultur, takich jak zmiana wielkości liter, formatowanie dat i liczb oraz porównywanie ciągów znakó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 pismo cyrylicę, a Latn określa pismo łacińskie. Nazwa kultury, która zawiera pismo, używa wzorca languagecode2
-scripttag
-country/regioncode2
. 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/regioncode2
-scripttag
, 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łą. Kultura chińska (uproszczona), o nazwie zh-Hans
, i kultura chińska (tradycyjna), o nazwie zh-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 przy użyciu klasy CultureAndRegionInfoBuilder
.
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ę. Twoja aplikacja określa niezmienną kulturę, używając pustego ciągu znaków ("") lub określając ją za pomocą 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 klasy CompareInfo dla neutralnej kultury nie jest zalecane, ponieważ zawarte w niej dane są arbitralne. Aby wyświetlić i sortować dane, określ język i region. Ponadto właściwość Name obiektu CompareInfo, utworzonego dla kultury neutralnej, zwraca tylko kraj i nie obejmuje 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ć właściwość Parent 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 zastępczego 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 to TaiwanCalendar, ale Thread.CurrentCulture nie jest ustawiony na zh-TW
, wtedy DateTimeFormatInfo.NativeCalendarName, DateTimeFormatInfo.GetEraName i DateTimeFormatInfo.GetAbbreviatedEraName zwracają pusty ciąg znaków ("").
Kultury niestandardowe
W systemie Windows można tworzyć niestandardowe ustawienia regionalne. Aby uzyskać więcej informacji, zobacz Niestandardowe ustawienia regionalne.
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-CN
, czyli język chiński (uproszczony, Chiny) i zh-TW
, czyli język chiński (tradycyjny, Tajwan), są dostępnymi kulturami w systemach Windows, ale posiadają aliasy w systemach Unix. "zh-CN" jest aliasem kultury "zh-Hans-CN", a "zh-TW" jest aliasem kultury "zh-Hant-TW". Kultury aliasowe nie są zwracane przez wywołania metody GetCultures i ich wartości właściwości mogą się różnić, w tym także kultury Parent, od tych w systemie Windows. W przypadku kultur zh-CN
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 kultur "zh-CN" lub "zh-TW", ale udostępniasz zasoby dla neutralnej kultury "zh-Hans" lub "zh-Hant", 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-Hant".
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 na wystąpieniu "zh-TW" CultureInfo i przekazywania do niego wystąpienia "zh-Hant-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 zmienić preferencje kulturowe. Aplikacje powinny zawsze uzyskiwać dane kulturowe podczas działania.
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. Aktualna kultura interfejsu użytkownika służy do pobierania zasobów specyficznych dla kultury w czasie działania.
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 element. Aby uzyskać bardziej szczegółowe informacje na temat bieżącej kultury interfejsu użytkownika, odwiedź temat dotyczący właściwości CultureInfo.CurrentUICulture.
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:
- Pobierając wartość CultureInfo.CurrentCulture właściwości.
- Pobierając wartość właściwości Thread.CurrentThread.CurrentCulture.
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 {culture1.Name}");
Console.WriteLine($"The two CultureInfo objects are equal: {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:
Pobierając wartość CultureInfo.CurrentUICulture właściwości.
Pobierając wartość właściwości Thread.CurrentThread.CurrentUICulture .
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 {uiCulture1.Name}");
Console.WriteLine($"The two CultureInfo objects are equal: {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:
Utwórz obiekt CultureInfo reprezentujący tę kulturę, wywołując konstruktor klasy CultureInfo i przekazując mu nazwę tej kultury. Konstruktor CultureInfo(String) tworzy instancję CultureInfo obiektu, który odzwierciedla zmiany dokonane przez użytkownika, jeśli nowa kultura jest taka sama jak bieżąca kultura systemu Windows. Konstruktor CultureInfo(String, Boolean) umożliwia określenie, czy obiekt CultureInfo uwzględnia przesłonięcia ustawione przez użytkownika, gdy nowa kultura jest taka sama jak bieżąca kultura systemu Windows.
Przypisz obiekt do właściwości CultureInfo lub CultureInfo.CurrentCulture 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 {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 {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 cokolwiek innego niż kultura słoweńska (Słowenia), zmienia obecną kulturę na słoweńską (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 {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 {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
Pobierz wszystkie kultury
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, osobno lub w połączeniu.
Poniższy przykład wywołuje metodę GetCultures dwukrotnie: najpierw z elementem członkowskim wyliczenia System.Globalization.CultureTypes w celu pobrania wszystkich kultur niestandardowych, a następnie z elementem System.Globalization.CultureTypes 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($" {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($" {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ę angielsko-amerykańską (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: '{Thread.CurrentThread.Name}'");
Console.WriteLine($"Current Thread Culture/UI Culture: {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($" {rnd.NextDouble() * 10:C2}");
}
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 tę kulturę do właściwości CultureInfo i DefaultThreadCurrentCulture. 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: '{Thread.CurrentThread.Name}'");
Console.WriteLine($"Current Thread Culture/UI Culture: {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($" {rnd.NextDouble() * 10:C2}");
}
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
Chociaż właściwości DefaultThreadCurrentCulture i DefaultThreadCurrentUICulture są statycznymi członkami, definiują domyślną kulturę i domyślną kulturę interfejsu użytkownika tylko dla domeny aplikacji, który jest aktualny w momencie ustawiania tych wartości. Aby uzyskać więcej informacji, zobacz następną sekcję, Kulturę i domeny aplikacji.
Podczas przypisywania wartości do właściwości DefaultThreadCurrentCulture i DefaultThreadCurrentUICulture, kultura oraz kultura interfejsu użytkownika wątków w domenie aplikacji również się zmieniają, jeśli nie zostały im jawnie przypisane żadne kultury. Jednak te wątki odzwierciedlają nowe ustawienia kultury wyłącznie 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 {DateTime.Now:D}");
}
public void DisplayCultures()
{
Console.WriteLine($"Application domain is {AppDomain.CurrentDomain.Id}");
Console.WriteLine($"Default Culture: {CultureInfo.DefaultThreadCurrentCulture}");
Console.WriteLine($"Default UI Culture: {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 asynchronicznego programowania opartego na zadaniach używa obiektów i Task do asynchronicznego wykonywania delegatów w wątkach puli. 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 właściwości CurrentCulture 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 przechodzi przez granice wątków i staje się bieżącą kulturą wątku, który wykonuje operację asynchroniczną.
Poniższy przykład przedstawia prostą ilustrację. W przykładzie zdefiniowano delegata Func<TResult> , formatDelegate
któ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). Następnie:
- Wywołuje delegata bezpośrednio, aby uruchomić go synchronicznie w głównym wątku aplikacji.
- Tworzy zadanie, które wykonuje delegat asynchronicznie w wątku w ramach puli wątków.
- Tworzy zadanie, które wykonuje delegat synchronicznie w głównym wątku aplikacji, poprzez wywołanie metody Task.RunSynchronously.
Jak pokazuje wynik z przykładu, gdy bieżąca kultura zostanie zmieniona na francuską (Francja), bieżąca kultura 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 deserializowana tylko w środowisku, w którym Name ma to 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. Na przykład kultura wprowadzona w systemie Windows 10 nie może być deserializowana w systemie Windows 8.
CultureTypes Jeśli wartość jest CultureTypes.UserCustomCulture, i ponieważ komputer, na którym jest deserializowana, nie ma zainstalowanej tej niestandardowej kultury użytkownika, nie można jej zdeserializować.
Jeśli wartość CultureTypes wynosi CultureTypes.ReplacementCultures, a komputer, na którym jest deserializowana, nie posiada tej kultury zastępczej, zostanie deserializowana z tą samą nazwą, ale nie wszystkimi takimi samymi cechami. Na przykład, jeśli
en-US
jest kulturą zastępczą na komputerze A, ale nie na komputerze B, i jeśli obiekt CultureInfo, odnoszący się do tej kultury, jest serializowany na komputerze A i deserializowany na komputerze B, żadne cechy niestandardowe kultury nie są przesyłane. Deserializacja kultury przebiega pomyślnie, ale skutkuje innym znaczeniem.
Panel sterowania nadpisaniami
Użytkownik może zdecydować się na nadpisanie niektórych wartości skojarzonych z bieżącą kulturą systemu Windows, korzystając z sekcji 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 nadpisywań, w tym ustawień użytkownika dla właściwości wystąpienia DateTimeFormatInfo zwracanych przez właściwość DateTimeFormat, oraz właściwości wystąpienia NumberFormatInfo zwracanych przez właściwość NumberFormat. Jeśli ustawienia użytkownika są niezgodne z kulturą skojarzoną z elementem CultureInfo, na przykład jeśli wybrany kalendarz nie jest jednym z OptionalCalendars, wyniki metod i wartości właściwości są niezdefiniowane.
Alternatywne kolejności sortowania
Niektóre kultury obsługują więcej niż jedną kolejność sortowania. Na przykład:
Kultura hiszpańska (Hiszpania) ma dwa sposoby sortowania: domyślną kolejność sortowania międzynarodowego i kolejność sortowania tradycyjnego. Podczas tworzenia wystąpienia obiektu CultureInfo z nazwą kultury
es-ES
używany jest międzynarodowy porządek sortowania. Podczas tworzenia obiektu CultureInfo z nazwą kulturyes-ES-tradnl
używana jest tradycyjna kolejność sortowania.Kultura
zh-CN
(chiński (uproszczony, CHRL)) obsługuje dwie kolejności sortowania: domyślnie przez wymowę i według liczby pociągnięć pędzla. Podczas tworzenia wystąpienia CultureInfo obiektu zzh-CN
nazwą kultury jest używana domyślna kolejność sortowania. Podczas tworzenia wystąpienia obiektu CultureInfo przy użyciu lokalnego identyfikatora 0x00020804 ciągi są sortowane według liczby kresek.
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 do sortowania i identyfikator |
---|---|---|---|
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 (Republika Ludowa Chin) | 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 | Sortowanie książki telefonicznej DIN: 0x00010407 |
hu-HU | Język 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 platformy uniwersalnej systemu Windows (UWP) właściwości CurrentCulture i CurrentUICulture są do odczytu i zapisu, podobnie jak w aplikacjach .NET Framework i .NET Core. Jednak aplikacje UWP 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 właściwości CurrentCulture i CurrentUICulture odzwierciedlają kulturę oraz 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. Ustawienie właściwości CurrentCulture lub CurrentUICulture zmienia kulturę całej aplikacji; kultury nie można ustawić dla każdego wątku osobno.