CultureInfo-Klasse

Dieser Artikel enthält ergänzende Hinweise zur Referenzdokumentation für diese API.

Die CultureInfo-Klasse stellt kulturspezifische Informationen bereit (z. B. Sprache, Subsprache, Land/Region, Kalender und Konventionen, die mit einer bestimmten Kultur verbunden sind). Diese Klasse bietet auch Zugriff auf kulturspezifische Instanzen der Objekte DateTimeFormatInfo, NumberFormatInfo, CompareInfo und TextInfo. Diese Objekte enthalten die Informationen, die für kulturspezifische Vorgänge erforderlich sind (z. B. Groß-/Kleinschreibung, Formatierung von Datumsangaben und Zahlen sowie Vergleichen von Zeichenfolgen). Die CultureInfo-Klasse wird entweder direkt oder indirekt von Klassen verwendet, die kulturspezifische Daten formatieren, parsen oder bearbeiten (z. B. String, DateTime und DateTimeOffset sowie numerische Typen).

Kulturnamen und -bezeichner

Die CultureInfo-Klasse gibt basierend auf RFC 4646 einen eindeutigen Namen für jede Kultur an. Der Name ist eine Kombination aus einem ISO 639-Kulturcode, der sich aus zwei oder drei Buchstaben zusammensetzt, kleingeschriebenen wird und einer Sprache zugeordnet ist, und einem ISO 3166-Subkulturcode, der aus zwei Buchstaben besteht, großgeschrieben wird und einem Land oder einer Region zugeordnet ist. Darüber hinaus werden für Apps, die unter Windows 10 oder höher ausgeführt werden, Kulturnamen unterstützt, die gültigen BCP-47-Sprachtags entsprechen.

Hinweis

Wenn ein Kulturname an einen Klassenkonstruktor oder eine Methode (z. B. CreateSpecificCulture oder CultureInfo) übergeben wird, ist die Groß- und Kleinschreibung nicht relevant.

Das Format für den Kulturnamen, der auf RFC 4646 basiert, lautet languagecode2-country/regioncode2, wobei languagecode2 der aus zwei Buchstaben bestehende Sprachcode und country/regioncode2 der aus zwei Buchstaben bestehende Subkulturcode ist. Beispiele hierfür sind ja-JP für „Japanisch (Japan)“ und en-US für „Englisch (USA)“. In Fällen, in denen kein aus zwei Buchstaben bestehender Sprachcode verfügbar ist, wird wie in ISO 639-3 definiert ein aus drei Buchstaben bestehender Code verwendet.

Einige Kulturnamen geben auch ein ISO 15924-Skript an. Beispielsweise gibt „Cyrl“ das kyrillische Skript und „Latn“ das lateinische Skript an. Ein Kulturname, der ein Skript enthält, verwendet das Muster languagecode2-scripttag-country/regioncode2. Ein Beispiel für diese Art von Kulturname ist uz-Cyrl-UZ für „Usbekisch (Kyrillisch, Usbekistan)“. Unter Windows-Betriebssystemen vor Windows Vista verwendet ein Kulturname, der ein Skript enthält, das Muster languagecode2-country/regioncode2-scripttag (z. B. uz-UZ-Cyrl für „Usbekisch (Kyrillisch, Usbekistan)“).

Eine neutrale Kultur wird nur durch den aus zwei Buchstaben bestehenden und kleingeschriebenen Sprachcode angegeben. fr gibt beispielsweise die neutrale Kultur für Französisch und de die neutrale Kultur für Deutsch an.

Hinweis

Es gibt zwei Kulturnamen, die dieser Regel widersprechen. Die Kulturen „Chinesisch (vereinfacht)“ (wird mit zh-Hans benannt) und „Chinesisch (traditionell)“ (wird mit zh-Hant benannt) sind neutrale Kulturen. Die Kulturnamen stellen den aktuellen Standard dar und sollten verwendet werden, es sei denn, Sie haben einen Grund für die Verwendung der älteren Namen zh-CHS und zh-CHT.

Ein Kulturbezeichner ist eine internationale numerische Standardabkürzung und umfasst die Komponenten, die erforderlich sind, um eine der installierten Kulturen eindeutig zu identifizieren. Ihre Anwendung kann vordefinierte Kulturbezeichner verwenden oder benutzerdefinierte Bezeichner definieren.

Bestimmte vordefinierte Kulturnamen und -bezeichner werden von dieser und anderen Klassen im System.Globalization-Namespace verwendet. Ausführliche Kulturinformationen für Windows-Systeme finden Sie in der Spalte Sprachtag in der Liste der von Windows unterstützten Sprach- und Regionsnamen. Kulturnamen befolgen den von BCP 47 definierten Standard.

Die Kulturnamen und -bezeichner stellen nur eine Teilmenge der Kulturen dar, die auf einem bestimmten Computer gefunden werden können. Windows-Versionen oder Service Packs können die verfügbaren Kulturen ändern. Anwendungen können benutzerdefinierte Kulturen mithilfe der CultureAndRegionInfoBuilder-Klasse hinzufügen. Benutzer*innen können ihre eigenen benutzerdefinierten Kulturen mithilfe des Tools Microsoft Locale Builder hinzufügen. Microsoft Locale Builder wird mithilfe der CultureAndRegionInfoBuilder-Klasse in verwaltetem Code geschrieben.

Mehrere unterschiedliche Namen sind eng mit einer Kultur verknüpft, insbesondere die Namen, die den folgenden Klassenmembern zugeordnet sind:

Invariante, neutrale und spezifische Kulturen

Die Kulturen sind in der Regel in drei Gruppen unterteilt: invariante Kulturen, neutrale Kulturen und spezifische Kulturen.

Eine invariante Kultur ist kulturunabhängig. Ihre Anwendung gibt die invariante Kultur mithilfe einer leeren Zeichenfolge ("") oder anhand des Bezeichners an. Die InvariantCulture-Eigenschaft definiert eine Instanz der invarianten Kultur. Sie ist mit der englischen Sprache verknüpft, aber nicht mit einem Land bzw. einer Region. Sie wird in fast jeder Methode im Globalization-Namespace verwendet, die eine Kultur erfordert.

Eine neutrale Kultur ist eine Kultur, die mit einer Sprache, aber nicht mit einem Land bzw. einer Region verknüpft ist. Eine spezifische Kultur ist eine Kultur, die einer Sprache und einem Land bzw. einer Region zugeordnet ist. Beispielsweise ist fr der neutrale Name für die Kultur „Französisch“ und fr-FR der Name der spezifischen Kultur „Französisch (Frankreich)“. Beachten Sie, dass „Chinesisch (vereinfacht)“ und „Chinesisch (traditionell)“ auch als neutrale Kulturen betrachtet werden.

Das Erstellen einer Instanz einer CompareInfo-Klasse für eine neutrale Kultur wird nicht empfohlen, da die darin enthaltenen Daten arbiträr sind. Geben Sie zum Anzeigen und Sortieren von Daten sowohl die Sprache als auch die Region an. Außerdem gibt die Eigenschaft Name eines Objekts CompareInfo, das für eine neutrale Kultur erstellt wird, nur das Land zurück. Die Region wird nicht einbezogen.

Die definierten Kulturen weisen eine Hierarchie auf, in der die übergeordnete Kultur einer spezifischen Kultur eine neutrale Kultur und die übergeordnete Kultur einer neutralen Kultur die invariante Kultur ist. Die Parent-Eigenschaft enthält die neutrale Kultur, die einer spezifischen Kultur zugeordnet ist. Benutzerdefinierte Kulturen sollten die Parent-Eigenschaft in Übereinstimmung mit diesem Muster definieren.

Wenn die Ressourcen für eine bestimmte Kultur unter dem Betriebssystem nicht verfügbar sind, werden die Ressourcen für die zugeordnete neutrale Kultur verwendet. Wenn die Ressourcen für die neutrale Kultur nicht verfügbar sind, werden die in die Hauptassembly eingebetteten Ressourcen verwendet. Weitere Informationen zum Ressourcenfallbackprozess finden Sie unter Packen und Bereitstellen von Ressourcen in .NET-Apps.

Die Liste der Gebietsschemas in der Windows-API unterscheidet sich geringfügig von der Liste der Kulturen, die von .NET unterstützt werden. Wenn die Interoperabilität mit Windows erforderlich ist (z. B. über den P/Invoke-Mechanismus), sollte die Anwendung eine spezifische Kultur verwenden, die für das Betriebssystem definiert ist. Die Verwendung der spezifischen Kultur sorgt für Konsistenz mit dem entsprechenden Windows-Gebietsschema, das mit einem Gebietsschemabezeichner identifiziert wird, der mit LCID identisch ist.

Ein DateTimeFormatInfo- bzw. NumberFormatInfo-Element kann nur für die invariante Kultur oder für spezifische Kulturen erstellt werden, nicht jedoch für neutrale Kulturen.

Wenn DateTimeFormatInfo.CalendarTaiwanCalendar entspricht, aber Thread.CurrentCulture nicht auf zh-TW festgelegt ist, geben DateTimeFormatInfo.NativeCalendarName, DateTimeFormatInfo.GetEraName und DateTimeFormatInfo.GetAbbreviatedEraName eine leere Zeichenfolge ("") zurück.

Benutzerdefinierte Kulturen

Unter Windows können Sie benutzerdefinierte Gebietsschemas erstellen. Weitere Informationen finden Sie unter Benutzerdefinierte Gebietsschemas.

„CultureInfo“ und Kulturdaten

.NET leitet seine Kulturdaten von einer Vielzahl von Quellen ab, je nach Implementierung, Plattform und Version:

  • In allen Versionen von .NET (Core), die auf UNIX-Plattformen oder unter Windows 10 und höheren Versionen ausgeführt werden, werden Kulturdaten von der ICU-Bibliothek (International Components for Unicode) bereitgestellt. Die spezifische Version der ICU-Bibliothek hängt vom jeweiligen Betriebssystem ab.
  • In allen Versionen von .NET (Core), die unter Windows 9 und früheren Versionen ausgeführt werden, werden Kulturdaten vom Windows-Betriebssystem bereitgestellt.
  • In .NET Framework 4 und höheren Versionen werden Kulturdaten vom Windows-Betriebssystem bereitgestellt.

Aus diesem Grund ist eine Kultur, die für eine bestimmte .NET-Implementierung, -Plattform oder -Version verfügbar ist, möglicherweise nicht für eine andere .NET-Implementierung, -Plattform oder -Version verfügbar.

Einige CultureInfo-Objekte unterscheiden sich je nach zugrunde liegender Plattform. Beispielsweise sind die Kulturen zh-CN („Chinesisch (vereinfacht, China)“) und zh-TW („Chinesisch (traditionell, Taiwan)“) unter Windows-Systemen verfügbar, unter UNIX-System sind dies jedoch Alias-Kulturen. "zh-CN" ist ein Alias für die "zh-Hans-CN"-Kultur, und "zh-TW" ist ein Alias für die "zh-Hant-TW"-Kultur. Aliaskulturen werden nicht durch Aufrufe der GetCultures-Methode zurückgegeben und weisen möglicherweise unterschiedliche Eigenschaftswerte auf (einschließlich verschiedener Parent-Kulturen) als ihre Windows-Entsprechungen. Bei den Kulturen zh-CN und zh-TW gibt es folgende Unterschiede:

  • Unter Windows-Systemen ist "zh-Hans" die übergeordnete Kultur der "zh-CN"-Kultur, und "zh-Hant" ist die übergeordnete Kultur der "zh-TW"-Kultur. Die übergeordnete Kultur dieser beiden Kulturen ist "zh". Auf UNIX-Systemen ist "zh" die übergeordnete Kultur dieser beiden Kulturen. Dies bedeutet, dass Ihre Anwendung die Ressourcen für die neutrale Kultur unter Windows lädt, nicht jedoch auf UNIX-Systemen, wenn Sie keine kulturspezifischen Ressourcen für die Kultur "zh-CN" bzw. "zh-TW" bereitstellen, für die neutrale Kultur "zh-Hans" bzw. "zh-Hant" hingegen schon. Auf UNIX-Systemen müssen Sie die CurrentUICulture-Eigenschaft des Threads explizit auf "zh-Hans" oder "zh-Hant" festlegen.

  • Wenn Sie unter Windows CultureInfo.Equals für eine Instanz aufrufen, die die Kultur "zh-CN" darstellt, und eine "zh-Hans-CN"-Instanz übergeben, wird true zurückgegeben. Auf UNIX-Systemen gibt der Methodenaufruf false zurück. Dieses Verhalten gilt auch für das Aufrufen von Equals für die CultureInfo-Instanz "zh-TW" und das Übergeben an die "zh-Hant-Tw"-Instanz.

Dynamische Kulturdaten

Mit Ausnahme der invarianten Kultur sind Kulturdaten dynamisch. Dies gilt auch für die vordefinierten Kulturen. Beispielsweise übernehmen Länder oder Regionen neue Währungen, die Rechtschreibung von Wörtern wird geändert, oder der bevorzugte Kalender wird verwendet. Kulturdefinitionen werden so geändert, dass sie dies nachverfolgen. Benutzerdefinierte Kulturen können ohne Hinweis geändert werden, und eine spezifische Kultur kann von einer benutzerdefinierten Ersatzkultur außer Kraft gesetzt werden. Einzelne Benutzer*innen können wie im Folgenden beschrieben auch Kultureinstellungen außer Kraft setzen. Anwendungen sollten zur Laufzeit immer Kulturdaten abrufen.

Achtung

Beim Speichern von Daten sollte Ihre Anwendung die invariante Kultur, ein Binärformat oder ein bestimmtes kulturunabhängiges Format verwenden. Daten, die gemäß den aktuellen Werten gespeichert werden, die einer bestimmten Kultur zugeordnet sind (außer der invarianten Kultur), können unlesbar werden, oder die Bedeutung ändert sich, wenn die Kultur geändert wird.

Aktuelle Kultur und aktuelle Benutzeroberflächenkultur

Jeder Thread in einer .NET-Anwendung verfügt über eine aktuelle Kultur und eine aktuelle Benutzeroberflächenkultur. Die aktuelle Kultur bestimmt die Formatierungskonventionen für Datumsangaben, Uhrzeiten, Zahlen und Währungswerte, die Sortierreihenfolge von Text, Groß- und Kleinschreibungskonventionen sowie die Art, wie Zeichenfolgen verglichen werden. Die aktuelle Benutzeroberflächenkultur wird verwendet, um kulturspezifische Ressourcen zur Laufzeit abzurufen.

Hinweis

Im Abschnitt Kultur und Threads wird erläutert, wie die aktuelle Kultur und die aktuelle Benutzeroberflächenkultur auf Threadbasis bestimmt wird. Weitere Informationen dazu, wie die aktuelle Kultur und die aktuelle Benutzeroberflächenkultur für Threads bestimmt wird, die in einer neuen Anwendungsdomäne ausgeführt werden, sowie zu Threads, die Anwendungsdomänengrenzen überschreiten, finden Sie im Abschnitt Kultur und Anwendungsdomänen. Wenn Sie herausfinden möchten, wie die aktuelle Kultur und die aktuelle Benutzeroberflächenkultur für Threads bestimmt wird, die aufgabenbasierte asynchrone Vorgänge ausführen, lesen Sie den Abschnitt Kultur und aufgabenbasierte asynchrone Vorgänge.

Ausführlichere Informationen zur aktuellen Kultur finden Sie im Artikel zur CultureInfo.CurrentCulture-Eigenschaft. Details zur aktuellen Benutzeroberflächenkultur sind im Artikel zur CultureInfo.CurrentUICulture-Eigenschaft enthalten.

Abrufen der aktuellen Kultur und der aktuellen Benutzeroberflächenkulturen

Sie können ein CultureInfo-Objekt, das die aktuelle Kultur darstellt, auf zwei Arten abrufen:

Im folgenden Beispiel werden beide Eigenschaftswerte abgerufen, verglichen (um zu zeigen, dass sie gleich sind), und dann wird der Name der aktuellen Kultur angezeigt.

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

Sie können ein CultureInfo-Objekt, das die aktuelle Benutzeroberflächenkultur darstellt, auf zwei Arten abrufen:

Im folgenden Beispiel werden beide Eigenschaftswerte abgerufen, verglichen (um zu zeigen, dass sie gleich sind), und dann wird der Name der aktuellen Benutzeroberflächenkultur angezeigt.

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

Festlegen der aktuellen Kultur und aktuellen Benutzeroberflächenkulturen

Gehen Sie wie folgt vor, um die Kultur und Benutzeroberflächenkultur eines Threads zu ändern:

  1. Instanziieren Sie ein CultureInfo-Objekt, das diese Kultur darstellt, indem Sie einen CultureInfo-Klassenkonstruktor aufrufen und den Namen der Kultur übergeben. Der CultureInfo(String)-Konstruktor instanziiert ein CultureInfo-Objekt, das benutzerdefinierte Außerkraftsetzungen widerspiegelt, wenn die neue Kultur mit der aktuellen Windows-Kultur identisch ist. Mit dem CultureInfo(String, Boolean)-Konstruktor können Sie angeben, ob das neu instanziierte CultureInfo-Objekt benutzerdefinierte Außerkraftsetzungen widerspiegelt, wenn die neue Kultur mit der aktuellen Windows-Kultur übereinstimmt.

  2. Weisen Sie der CultureInfo.CurrentCulture- oder CultureInfo.CurrentUICulture-Eigenschaft bei .NET Core und .NET Framework 4.6 und höheren Versionen das CultureInfo-Objekt zu.

Im folgenden Beispiel wird die aktuelle Kultur abgerufen. Wenn es sich um eine andere Kultur als die Kultur „Französisch (Frankreich)“ handelt, wird die aktuelle Kultur in „Französisch (Frankreich)“ geändert. Andernfalls wird die aktuelle Kultur in „Französisch (Luxemburg)“ geändert.

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

Im folgenden Beispiel wird die aktuelle Kultur abgerufen. Wenn es sich um eine andere Kultur als die Kultur „Slowenisch (Slowenien)“ handelt, wird die aktuelle Kultur in „Slowenisch (Slowenien)“ geändert. Andernfalls wird die aktuelle Kultur in „Kroatisch (Kroatien)“ geändert.

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

Abrufen aller Kulturen

Sie können ein Array von bestimmten Kategorien von Kulturen oder aller Kulturen abrufen, die auf dem lokalen Computer verfügbar sind, indem Sie die GetCultures-Methode aufrufen. Sie können beispielsweise benutzerdefinierte, spezifische oder neutrale Kulturen entweder allein oder in Kombination abrufen.

Im folgenden Beispiel wird die GetCultures-Methode zweimal aufgerufen: zuerst mit dem Enumerationsmember System.Globalization.CultureTypes, um alle benutzerdefinierten Kulturen abzurufen, und dann mit dem Enumerationsmember System.Globalization.CultureTypes, um alle Ersatzkulturen abzurufen.

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.

Kultur und Threads

Wenn ein neuer Anwendungsthread gestartet wird, werden die aktuelle Kultur und die aktuelle Benutzeroberflächenkultur von der aktuellen Systemkultur und nicht von der aktuellen Threadkultur definiert. Der Unterschied wird im folgenden Beispiel veranschaulicht. Sie legt die aktuelle Kultur und die aktuelle Benutzeroberflächenkultur eines Anwendungsthreads auf die Kultur "fr-FR" („Französisch (Frankreich)“) fest. Wenn die aktuelle Kultur bereits "fr-FR" lautet, wird sie im Beispiel auf die Kultur "en-US" („Englisch (USA)“) festgelegt. Es werden drei Zufallszahlen als Währungswerte angezeigt, und dann wird ein neuer Thread erstellt, der wiederum drei weitere Zufallszahlen als Währungswerte anzeigt. Wie die Ausgabe des Beispiels zeigt, spiegeln die Währungswerte, die vom neuen Thread angezeigt werden, nicht die Formatierungskonventionen der Kultur „Französisch (Frankreich)“ wider (im Gegensatz zur Ausgabe des Hauptanwendungsthreads).

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

Sie können die Kultur und Benutzeroberflächenkultur aller Threads in einer Anwendungsdomäne festlegen, indem Sie den Eigenschaften DefaultThreadCurrentCulture und DefaultThreadCurrentUICulture ein CultureInfo-Objekt zuweisen, das diese Kultur darstellt. Im folgenden Beispiel werden diese Eigenschaften verwendet, um sicherzustellen, dass alle Threads in der Standardanwendungsdomäne dieselbe Kultur aufweisen.

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 €

Warnung

Obwohl es sich bei den Eigenschaften DefaultThreadCurrentCulture und DefaultThreadCurrentUICulture um statische Member handelt, definieren sie die Standardkultur und die Benutzeroberflächen-Standardkultur nur für die Anwendungsdomäne, die zum Zeitpunkt der Festlegung dieser Eigenschaftswerte aktuell ist. Weitere Informationen finden Sie im nächsten Abschnitt Kultur und Anwendungsdomänen.

Wenn Sie den Eigenschaften DefaultThreadCurrentCulture und DefaultThreadCurrentUICulture Werte zuweisen und den Threads nicht explizit eine Kultur zugewiesen wurde, werden die Kultur und die Benutzeroberflächenkultur der Threads in der Anwendungsdomäne ebenfalls geändert. Diese Threads spiegeln jedoch nur die neuen Kultureinstellungen wider, während sie in der aktuellen Anwendungsdomäne ausgeführt werden. Wenn diese Threads in einer anderen Anwendungsdomäne ausgeführt werden, wird ihre Kultur zur Standardkultur, die für diese Anwendungsdomäne definiert ist. Daher wird empfohlen, dass Sie immer die Kultur des Hauptanwendungsthreads festlegen und sich nicht darauf verlassen, dass die Eigenschaften DefaultThreadCurrentCulture und DefaultThreadCurrentUICulture diese ändern.

Kultur und Anwendungsdomänen

DefaultThreadCurrentCulture und DefaultThreadCurrentUICulture sind statische Eigenschaften, die explizit eine Standardkultur nur für die Anwendungsdomäne definieren, die aktuell ist, wenn der Eigenschaftswert festgelegt oder abgerufen wird. Im folgenden Beispiel wird die Standardkultur und die Benutzeroberflächen-Standardkultur in der Standardanwendungsdomäne auf „Französisch (Frankreich)“ festgelegt. Anschließend wird die AppDomainSetup-Klasse und der AppDomainInitializer-Delegat verwendet, um die Standardkultur und die Benutzeroberflächenkultur in einer neuen Anwendungsdomäne auf „Russisch (Russland)“ festzulegen. Ein einzelner Thread führt dann zwei Methoden in jeder Anwendungsdomäne aus. Beachten Sie, dass die Kultur und die Benutzeroberflächenkultur des Threads nicht explizit festgelegt sind. Sie werden von der Standardkultur und der Benutzeroberflächenkultur der Anwendungsdomäne abgeleitet, in der der Thread ausgeführt wird. Beachten Sie auch, dass die Eigenschaften DefaultThreadCurrentCulture und DefaultThreadCurrentUICulture die CultureInfo-Standardwerte der Anwendungsdomäne zurückgeben, die beim Ausführen des Methodenaufrufs aktuell ist.

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

Weitere Informationen zu Kulturen und Anwendungsdomänen finden Sie im Abschnitt „Anwendungsdomänen und Threads“ im Artikel Anwendungsdomänen.

Kultur und aufgabenbasierte asynchrone Vorgänge

Beim aufgabenbasierten asynchronen Programmiermuster werden Task- und Task<TResult>-Objekte zum asynchronen Ausführen von Delegaten in Threadpoolthreads verwendet. Der spezifische Thread, für den eine bestimmte Aufgabe ausgeführt wird, ist im Voraus nicht bekannt, wird aber zur Laufzeit bestimmt.

Für Apps, die auf .NET Framework 4.6 oder eine höhere Version ausgelegt sind, ist die Kultur Teil des Kontexts eines asynchronen Vorgangs. Anders ausgedrückt erben asynchrone Vorgänge standardmäßig die Werte der CurrentCulture- und CurrentUICulture-Eigenschaften des Threads, über den sie gestartet werden. Wenn sich die aktuelle Kultur oder die aktuelle Benutzeroberflächenkultur von der Systemkultur unterscheidet, überschreitet die aktuelle Kultur Threadgrenzen und wird zur aktuellen Kultur des Threadpoolthreads, der einen asynchronen Vorgang ausführt.

Das folgende Beispiel bietet eine einfache Veranschaulichung. Im Beispiel wird der Func<TResult>-Delegat formatDelegate definiert, der einige Zahlen zurückgibt, die als Währungswerte formatiert sind. Im Beispiel wird die aktuelle Systemkultur in „Französisch (Frankreich)“ bzw. in „Englisch (USA)“ geändert, wenn „Französisch (Frankreich)“ bereits die aktuelle Kultur ist. Es wird dann Folgendes ausgeführt:

  • Der Delegat wird direkt aufgerufen, sodass er synchron im Haupt-App-Thread ausgeführt wird.
  • Eine Aufgabe wird erstellt, die den Delegaten asynchron in einem Threadpoolthread ausführt.
  • Eine Aufgabe wird erstellt, die den Delegaten synchron im Haupt-App-Thread ausführt, indem die Task.RunSynchronously-Methode aufgerufen wird.

Wie die Ausgabe des Beispiels zeigt, wird die aktuelle Kultur des Threads, über den Aufgaben asynchron aufgerufen werden, zur aktuellen Kultur für diesen asynchronen Vorgang, wenn die aktuelle Kultur in „Französisch (Frankreich)“ geändert wird.

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 und DefaultThreadCurrentUICulture sind App-basierte Domäneneigenschaften. Dies bedeutet, dass sie eine Standardkultur für alle Threads einrichten, denen nicht explizit eine Kultur in einer bestimmten Anwendungsdomäne zugewiesen wurde. Bei Apps, die auf .NET Framework 4.6 oder höher ausgerichtet sind, bleibt die Kultur des aufrufenden Threads jedoch Teil des Kontexts einer asynchronen Aufgabe, auch wenn die Aufgabe App-Domänengrenzen überschreitet.

Serialisierung des CultureInfo-Objekts

Wenn ein CultureInfo-Objekt serialisiert wird, sind Name und UseUserOverride alles, was tatsächlich gespeichert wird. Es wird nur in einer Umgebung erfolgreich deserialisiert, in der Name dieselbe Bedeutung hat. Die folgenden drei Beispiele zeigen, warum dies nicht immer der Fall ist:

  • Wenn der CultureTypes-Eigenschaftswert CultureTypes.InstalledWin32Cultures lautet und diese Kultur erstmals in einer bestimmten Version des Windows-Betriebssystems eingeführt wurde, ist eine Deserialisierung des Objekts in einer früheren Windows-Version nicht möglich. Wenn beispielsweise eine Kultur in Windows 10 eingeführt wurde, kann das Objekt unter Windows 8 nicht deserialisiert werden.

  • Wenn der CultureTypes-Wert CultureTypes.UserCustomCulture entspricht und auf dem Computer, auf dem es deserialisiert wird, diese benutzerdefinierte Kultur nicht installiert ist, ist keine Deserialisierung möglich.

  • Wenn der CultureTypes-Wert CultureTypes.ReplacementCultures lautet und der Computer, auf dem das Objekt deserialisiert wird, nicht über diese Ersatzkultur verfügt, wird es auf denselben Namen, aber nicht mit den gleichen Merkmalen deserialisiert. Wenn es sich bei en-US beispielsweise um eine Ersatzkultur auf Computer A, nicht jedoch auf Computer B handelt, und ein CultureInfo-Objekt, das auf diese Kultur verweist, auf Computer A serialisiert und auf Computer B deserialisiert wird, werden keine der benutzerdefinierten Merkmale der Kultur übertragen. Die Kultur wird erfolgreich deserialisiert, aber mit einer anderen Bedeutung.

Außerkraftsetzung von Systemsteuerungsoptionen

Die Benutzer*innen können über den Bereich für Regions- und Sprachoptionen der Systemsteuerung einige der Werte außer Kraft setzen, die der aktuellen Kultur von Windows zugeordnet sind. Beispielsweise können Benutzer*innen das Datum in einem anderen Format anzeigen oder eine andere Währung als die Standardwährung für die Kultur verwenden. Im Allgemeinen sollten Ihre Anwendungen diese benutzerdefinierten Außerkraftsetzungen berücksichtigen.

Wenn UseUserOverridetrue entspricht und die angegebene Kultur mit der aktuellen Windows-Kultur übereinstimmt, verwendet CultureInfo diese Außerkraftsetzungen (einschließlich der Benutzereinstellungen für die Eigenschaften der DateTimeFormatInfo-Instanz, die von der DateTimeFormat-Eigenschaft zurückgegeben werden, und die Eigenschaften der NumberFormatInfo-Instanz, die von der NumberFormat-Eigenschaft zurückgegeben werden). Wenn die Benutzereinstellungen nicht mit der Kultur kompatibel sind, die CultureInfo zugeordnet ist (z. B. wenn der ausgewählte Kalender nicht einer der OptionalCalendars ist), werden die Ergebnisse der Methoden und die Werte der Eigenschaften nicht definiert.

Alternative Sortierreihenfolgen

Einige Kulturen unterstützten mehr als eine Sortierreihenfolge. Beispiel:

  • Die Kultur „Spanisch (Spanien)“ weist zwei Sortierreihenfolgen auf: die internationale Standardsortierreihenfolge und die traditionelle Sortierreihenfolge. Wenn Sie ein CultureInfo-Objekt mit dem Kulturnamen es-ES instanziieren, wird die internationale Sortierreihenfolge verwendet. Wenn Sie ein CultureInfo-Objekt mit dem Kulturnamen es-ES-tradnl instanziieren, wird die traditionelle Sortierreihenfolge verwendet.

  • Die zh-CN-Kultur („Chinesisch (vereinfacht, PRC)“) unterstützt zwei Sortierreihenfolgen: nach Aussprache (Standard) und nach Strichanzahl. Wenn Sie ein CultureInfo-Objekt mit dem Kulturnamen zh-CN instanziieren, wird die Standardsortierreihenfolge verwendet. Wenn Sie ein CultureInfo-Objekt mit dem lokalen Bezeichner 0x00020804 instanziieren, werden Zeichenfolgen nach Strichanzahl sortiert.

Die folgende Tabelle enthält die Kulturen, die unterschiedliche Sortierreihenfolgen unterstützen, sowie die Bezeichner für die standardmäßigen und die alternativen Sortierreihenfolgen.

Kulturname Kultur Standardsortierreihenfolge und Bezeichner Alternative Sortierreihenfolge und Bezeichner
es-ES Spanisch (Spanien) International: 0x00000C0A Traditionell: 0x0000040A
zh-TW Chinesisch (Taiwan) Anzahl der Striche: 0x00000404 Bopomofo: 0x00030404
zh-CN Chinesisch (VRC) Aussprache: 0x00000804 Anzahl der Striche: 0x00020804
zh-HK Chinesisch (Hongkong SAR) Anzahl der Striche: 0x00000c04 Anzahl der Striche: 0x00020c04
zh-SG Chinesisch (Singapur) Aussprache: 0x00001004 Anzahl der Striche: 0x00021004
zh-MO Chinesisch (Macao SAR) Aussprache: 0x00001404 Anzahl der Striche: 0x00021404
ja-JP Japanisch (Japan) Standard: 0x00000411 Unicode: 0x00010411
ko-KR Koreanisch (Korea) Standard: 0x00000412 Koreanisch Xwansung – Unicode: 0x00010412
de-DE Deutsch (Deutschland) Wörterbuch: 0x00000407 Telefonbuchsortierung DIN: 0x00010407
hu-HU Ungarisch (Ungarn) Standard: 0x0000040e Technische Sortierung: 0x0001040e
ka-GE Georgisch (Georgien) Traditionell: 0x00000437 Moderne Sortierung: 0x00010437

Aktuelle Kultur und UWP-Apps

In UWP-Apps (Universelle Windows-Plattform) sind die Eigenschaften CurrentCulture und CurrentUICulture wie in .NET Framework- und .NET Core-Apps nicht lese- oder schreibgeschützt. UWP-Apps erkennen jedoch eine einzelne Kultur. Die Eigenschaften CurrentCulture und CurrentUICulture werden dem ersten Wert in der Sammlung Windows.ApplicationModel.Resources.Core.ResourceManager.DefaultContext.Languages zugeordnet.

Bei .NET-Apps handelt es sich bei der aktuellen Kultur um eine threadbasierte Einstellung, und die Eigenschaften CurrentCulture und CurrentUICulture spiegeln nur die Kultur und die Benutzeroberflächenkultur des aktuellen Threads wider. In UWP-Apps wird die aktuelle Kultur der Sammlung Windows.ApplicationModel.Resources.Core.ResourceManager.DefaultContext.Languages zugeordnet, bei der es sich um eine globale Einstellung handelt. Wenn Sie die Eigenschaft CurrentCulture oder CurrentUICulture festlegen, wird die Kultur der gesamten App geändert. Die Kultur kann nicht auf Threadbasis festgelegt werden.