Freigeben über


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

Die NumberFormatInfo Klasse enthält kulturspezifische Informationen, die beim Formatieren und Analysieren numerischer Werte verwendet werden. Diese Informationen umfassen das Währungssymbol, das Dezimalsymbol, das Gruppentrennzeichen und die Symbole für positive und negative Zeichen.

Instanziieren eines NumberFormatInfo-Objekts

Sie können ein NumberFormatInfo Objekt instanziieren, das die Formatierungskonventionen der aktuellen Kultur, der invarianten Kultur, einer bestimmten Kultur oder einer neutralen Kultur darstellt.

Instanziieren eines NumberFormatInfo-Objekts für die aktuelle Kultur

Sie können ein NumberFormatInfo Objekt für die aktuelle Kultur auf eine der folgenden Arten instanziieren. In jedem Fall ist das zurückgegebene NumberFormatInfo-Objekt schreibgeschützt.

Im folgenden Beispiel werden diese drei Methoden zum Erstellen NumberFormatInfo von Objekten verwendet, die die Formatierungskonventionen der aktuellen Kultur darstellen. Außerdem wird der Wert der IsReadOnly-Eigenschaft abgerufen, um zu veranschaulichen, dass jedes Objekt schreibgeschützt ist.

using System;
using System.Globalization;

public class InstantiateEx1
{
    public static void Main()
    {
        NumberFormatInfo current1 = CultureInfo.CurrentCulture.NumberFormat;
        Console.WriteLine(current1.IsReadOnly);

        NumberFormatInfo current2 = NumberFormatInfo.CurrentInfo;
        Console.WriteLine(current2.IsReadOnly);

        NumberFormatInfo current3 = NumberFormatInfo.GetInstance(CultureInfo.CurrentCulture);
        Console.WriteLine(current3.IsReadOnly);
    }
}
// The example displays the following output:
//       True
//       True
//       True

Sie können ein beschreibbares NumberFormatInfo Objekt erstellen, das die Konventionen der aktuellen Kultur auf eine der folgenden Arten darstellt:

Das folgende Beispiel veranschaulicht diese beiden Methoden zum Instanziieren eines NumberFormatInfo-Objekts und zeigt den Wert seiner IsReadOnly-Eigenschaft an, um zu veranschaulichen, dass das Objekt nicht schreibgeschützt ist.

using System;
using System.Globalization;

public class InstantiateEx2
{
    public static void Main()
    {
        NumberFormatInfo current1 = NumberFormatInfo.CurrentInfo;
        current1 = (NumberFormatInfo)current1.Clone();
        Console.WriteLine(current1.IsReadOnly);

        CultureInfo culture2 = CultureInfo.CreateSpecificCulture(CultureInfo.CurrentCulture.Name);
        NumberFormatInfo current2 = culture2.NumberFormat;
        Console.WriteLine(current2.IsReadOnly);
    }
}
// The example displays the following output:
//       False
//       False

Beachten Sie, dass das Windows-Betriebssystem es dem Benutzer ermöglicht, einige der Eigenschaftswerte außer Kraft zu setzen, die NumberFormatInfo in numerischen Formatierungs- und Analysevorgängen über das Element Region und Sprache in der Systemsteuerung verwendet werden. Beispielsweise kann ein Benutzer, dessen Kultur Englisch (USA) ist, währungswerte als 1,1 USD anstelle des Standardwerts von 1,1 US-Dollar anzeigen. Die NumberFormatInfo-Objekte, die wie zuvor beschrieben abgerufen wurden, spiegeln diese benutzerdefinierten Außerkraftsetzungen wider. Wenn dies nicht erwünscht ist, können Sie ein NumberFormatInfo-Objekt erstellen, das keine benutzerdefinierte Außerkraftsetzungen widerspiegelt (und das auch Lese-/Schreibvorgänge zulässt statt schreibgeschützt zu sein), indem Sie den CultureInfo.CultureInfo(String, Boolean)-Konstruktor aufrufen und einen false-Wert für das useUserOverride-Argument angeben. Das folgende Beispiel zeigt eine Abbildung für ein System, dessen aktuelle Kultur Englisch (USA) ist und dessen Währungssymbol von der Standardeinstellung von $in USD geändert wurde.

using System;
using System.Globalization;

public class InstantiateEx3
{
    public static void Main()
    {
        CultureInfo culture;
        NumberFormatInfo nfi;

        culture = CultureInfo.CurrentCulture;
        nfi = culture.NumberFormat;
        Console.WriteLine($"Culture Name:    {culture.Name}");
        Console.WriteLine($"User Overrides:  {culture.UseUserOverride}");
        Console.WriteLine($"Currency Symbol: {culture.NumberFormat.CurrencySymbol}\n");

        culture = new CultureInfo(CultureInfo.CurrentCulture.Name, false);
        Console.WriteLine($"Culture Name:    {culture.Name}");
        Console.WriteLine($"User Overrides:  {culture.UseUserOverride}");
        Console.WriteLine($"Currency Symbol: {culture.NumberFormat.CurrencySymbol}");
    }
}
// The example displays the following output:
//       Culture Name:    en-US
//       User Overrides:  True
//       Currency Symbol: USD
//
//       Culture Name:    en-US
//       User Overrides:  False
//       Currency Symbol: $

Wenn die CultureInfo.UseUserOverride-Eigenschaft auf true ist, werden die Eigenschaften CultureInfo.DateTimeFormat, CultureInfo.NumberFormat und CultureInfo.TextInfo ebenfalls aus den Benutzereinstellungen abgerufen. Wenn die Benutzereinstellungen nicht mit der kultur kompatibel sind, die dem CultureInfo Objekt zugeordnet ist (z. B. wenn der ausgewählte Kalender nicht einer der von der OptionalCalendars Eigenschaft aufgelisteten Kalender ist), sind die Ergebnisse der Methoden und die Werte der Eigenschaften nicht definiert.

Instanziieren eines NumberFormatInfo-Objekts für die invariante Kultur

Die invariante Kultur stellt eine Kultur dar, die kulturunempfindlich ist. Sie basiert auf der englischen Sprache, aber nicht auf einem bestimmten englischsprachigen Land/einer bestimmten Region. Obwohl die Daten bestimmter Kulturen dynamisch sein können und sich ändern können, um neue kulturelle Konventionen oder Benutzerpräferenzen widerzuspiegeln, ändern sich die Daten der invarianten Kultur nicht. Ein NumberFormatInfo Objekt, das die Formatierungskonventionen der invarianten Kultur darstellt, kann für Formatierungsvorgänge verwendet werden, in denen Ergebniszeichenfolgen nicht je nach Kultur variieren sollten.

Sie können ein NumberFormatInfo Objekt instanziieren, das die Formatierungskonventionen der invarianten Kultur auf folgende Weise darstellt:

Im folgenden Beispiel wird jede dieser Methoden verwendet, um ein NumberFormatInfo Objekt zu instanziieren, das die invariante Kultur darstellt. Anschließend wird angegeben, ob das Objekt schreibgeschützt ist.

using System;
using System.Globalization;

public class InstantiateEx4
{
    public static void Main()
    {
        NumberFormatInfo nfi;

        nfi = System.Globalization.NumberFormatInfo.InvariantInfo;
        Console.WriteLine(nfi.IsReadOnly);

        nfi = CultureInfo.InvariantCulture.NumberFormat;
        Console.WriteLine(nfi.IsReadOnly);

        nfi = new NumberFormatInfo();
        Console.WriteLine(nfi.IsReadOnly);
    }
}
// The example displays the following output:
//       True
//       True
//       False

Instanziieren eines NumberFormatInfo-Objekts für eine bestimmte Kultur

Eine bestimmte Kultur stellt eine Sprache dar, die in einem bestimmten Land/einer bestimmten Region gesprochen wird. Beispielsweise ist en-US eine bestimmte Kultur, die die in den USA gesprochene Englischsprache darstellt, und en-CA eine bestimmte Kultur ist, die die in Kanada gesprochene Englischsprache darstellt. Sie können ein NumberFormatInfo Objekt instanziieren, das die Formatierungskonventionen einer bestimmten Kultur auf folgende Weise darstellt:

Im folgenden Beispiel werden diese vier Methoden verwendet, um ein NumberFormatInfo Objekt zu erstellen, das die Formatierungskonventionen der indonesischen Kultur (Indonesien) widerspiegelt. Außerdem wird angegeben, ob jedes dieser Objekte schreibgeschützt ist.

using System;
using System.Globalization;

public class InstantiateEx5
{
    public static void Main()
    {
        CultureInfo culture;
        NumberFormatInfo nfi;

        nfi = CultureInfo.GetCultureInfo("id-ID").NumberFormat;
        Console.WriteLine($"Read-only: {nfi.IsReadOnly}");

        culture = new CultureInfo("id-ID");
        nfi = NumberFormatInfo.GetInstance(culture);
        Console.WriteLine($"Read-only: {nfi.IsReadOnly}");

        culture = CultureInfo.CreateSpecificCulture("id-ID");
        nfi = culture.NumberFormat;
        Console.WriteLine($"Read-only: {nfi.IsReadOnly}");

        culture = new CultureInfo("id-ID");
        nfi = culture.NumberFormat;
        Console.WriteLine($"Read-only: {nfi.IsReadOnly}");
    }
}
// The example displays the following output:
//       Read-only: True
//       Read-only: False
//       Read-only: False
//       Read-only: False

Instanziieren eines NumberFormatInfo-Objekts für eine neutrale Kultur

Eine neutrale Kultur stellt eine Kultur oder Sprache dar, die unabhängig von einem Land/einer Region ist. Es handelt sich in der Regel um das übergeordnete Element einer oder mehrerer bestimmter Kulturen. Beispielsweise ist „fr“ eine neutrale Kultur für die Sprache „Französisch“ und die übergeordnete Kultur der Kultur „fr-FR“. Sie erstellen ein NumberFormatInfo Objekt, das die Formatierungskonventionen einer neutralen Kultur auf die gleiche Weise darstellt, wie Sie ein NumberFormatInfo Objekt erstellen, das die Formatierungskonventionen einer bestimmten Kultur darstellt.

Da es jedoch unabhängig von einem bestimmten Land/einer bestimmten Region ist, fehlt eine neutrale Kultur kulturspezifische Formatierungsinformationen. Anstatt das NumberFormatInfo Objekt mit generischen Werten zu füllen, gibt .NET ein NumberFormatInfo Objekt zurück, das die Formatierungskonventionen einer bestimmten Kultur widerspiegelt, die ein untergeordnetes Element der neutralen Kultur ist. Beispielsweise spiegelt das NumberFormatInfo Objekt für die neutrale Kultur die Formatierungskonventionen der en-US Kultur wider, und das NumberFormatInfo Objekt für die Fr-Kultur spiegelt die Formatierungskonventionen der fr-FR Kultur wider.

Sie können Code wie das folgende verwenden, um zu bestimmen, welche Formatierungskonventionen für die jeweilige Kultur jede neutrale Kultur darstellt.

using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.Reflection;

public class InstantiateEx6
{
    public static void Main()
    {
        // Get all the neutral cultures
        List<String> names = new List<String>();
        Array.ForEach(CultureInfo.GetCultures(CultureTypes.NeutralCultures),
                      culture => names.Add(culture.Name));
        names.Sort();
        foreach (var name in names)
        {
            // Ignore the invariant culture.
            if (name == "") continue;

            ListSimilarChildCultures(name);
        }
    }

    private static void ListSimilarChildCultures(string name)
    {
        // Create the neutral NumberFormatInfo object.
        NumberFormatInfo nfi = CultureInfo.GetCultureInfo(name).NumberFormat;
        // Retrieve all specific cultures of the neutral culture.
        CultureInfo[] cultures = Array.FindAll(CultureInfo.GetCultures(CultureTypes.SpecificCultures),
                                 culture => culture.Name.StartsWith(name + "-", StringComparison.OrdinalIgnoreCase));
        // Create an array of NumberFormatInfo properties
        PropertyInfo[] properties = typeof(NumberFormatInfo).GetProperties(BindingFlags.Instance | BindingFlags.Public);
        bool hasOneMatch = false;

        foreach (var ci in cultures)
        {
            bool match = true;
            // Get the NumberFormatInfo for a specific culture.
            NumberFormatInfo specificNfi = ci.NumberFormat;
            // Compare the property values of the two.
            foreach (var prop in properties)
            {
                // We're not interested in the value of IsReadOnly.
                if (prop.Name == "IsReadOnly") continue;

                // For arrays, iterate the individual elements to see if they are the same.
                if (prop.PropertyType.IsArray)
                {
                    IList nList = (IList)prop.GetValue(nfi, null);
                    IList sList = (IList)prop.GetValue(specificNfi, null);
                    if (nList.Count != sList.Count)
                    {
                        match = false;
                        break;
                    }

                    for (int ctr = 0; ctr < nList.Count; ctr++)
                    {
                        if (!nList[ctr].Equals(sList[ctr]))
                        {
                            match = false;
                            break;
                        }
                    }
                }
                else if (!prop.GetValue(specificNfi).Equals(prop.GetValue(nfi)))
                {
                    match = false;
                    break;
                }
            }
            if (match)
            {
                Console.WriteLine($"NumberFormatInfo object for '{name}' matches '{ci.Name}'");
                hasOneMatch = true;
            }
        }
        if (!hasOneMatch)
            Console.WriteLine($"NumberFormatInfo object for '{name}' --> No Match");

        Console.WriteLine();
    }
}

Dynamische Daten

Die kulturspezifischen Daten zum Formatieren numerischer Werte, die von der NumberFormatInfo Klasse bereitgestellt werden, sind dynamisch, genau wie die kulturspezifischen Daten der CultureInfo Klasse. Sie sollten keine Annahmen über die Stabilität von Werten für NumberFormatInfo Objekte treffen, die bestimmten CultureInfo Objekten zugeordnet sind. Nur die daten, die von der invarianten Kultur und dem zugeordneten NumberFormatInfo Objekt bereitgestellt werden, sind stabil. Andere Daten können sich aus folgenden Gründen zwischen Anwendungssitzungen oder sogar innerhalb einer einzelnen Sitzung ändern:

  • Systemupdates: Kulturelle Vorlieben wie währungssymbole oder Währungsformate ändern sich im Laufe der Zeit. In diesem Fall umfasst Windows Update Änderungen im Zusammenhang mit dem NumberFormatInfo-Eigenschaftswert für eine bestimmte Kultur.

  • Ersetzungskulturen. Die CultureAndRegionInfoBuilder Klasse kann verwendet werden, um die Daten einer vorhandenen Kultur zu ersetzen.

  • Kaskadierende Änderungen an Eigenschaftswerten Eine Reihe kulturbezogener Eigenschaften kann sich zur Laufzeit ändern, was wiederum dazu führt, dass sich NumberFormatInfo Daten ändern. Beispielsweise kann die aktuelle Kultur programmgesteuert oder durch Benutzeraktion geändert werden. In diesem Fall ändert sich das von der NumberFormatInfo-Eigenschaft zurückgegebene CurrentInfo-Objekt in ein Objekt, das der aktuellen Kultur zugeordnet ist.

  • Benutzereinstellungen. Benutzer Ihrer Anwendung überschreiben möglicherweise einige der Werte, die der aktuellen Systemkultur zugeordnet sind, über die Region und Sprachoptionen in der Systemsteuerung. Beispielsweise können Benutzer ein anderes Währungssymbol oder ein anderes Dezimaltrennzeichen auswählen. Wenn die CultureInfo.UseUserOverride Eigenschaft auf true (standardwert) festgelegt ist, werden die Eigenschaften des NumberFormatInfo Objekts auch aus den Benutzereinstellungen abgerufen.

Alle benutzerübersteuerbaren Eigenschaften eines NumberFormatInfo Objekts werden initialisiert, wenn das Objekt erstellt wird. Es besteht immer noch die Möglichkeit der Inkonsistenz, da weder die Objekterstellung noch der Benutzerüberschreibungsprozess atomar sind und sich die relevanten Werte während der Objekterstellung ändern können. Diese Inkonsistenzen sollten jedoch äußerst selten sein.

Sie können steuern, ob Benutzervorgaben in NumberFormatInfo-Objekten berücksichtigt werden, die dieselbe Kultur wie die aktuelle Kultur darstellen. In der folgenden Tabelle sind die Methoden aufgeführt, mit denen ein NumberFormatInfo Objekt abgerufen werden kann, und gibt an, ob das resultierende Objekt Benutzerüberschreibungen widerspiegelt.

Quelle des CultureInfo- und NumberFormatInfo-Objekts Spiegelt benutzerdefinierte Außerkraftsetzungen wider
CultureInfo.CurrentCulture.NumberFormat-Eigenschaft Ja
NumberFormatInfo.CurrentInfo-Eigenschaft Ja
CultureInfo.CreateSpecificCulture-Methode Ja
CultureInfo.GetCultureInfo-Methode Nein
CultureInfo(String) Konstruktor Ja
CultureInfo.CultureInfo(String, Boolean) Konstruktor Hängt vom Wert des useUserOverride Parameters ab.

Es sei denn, es gibt einen zwingenden Grund, dies nicht zu tun, sollten Sie Benutzerüberschreibungen berücksichtigen, wenn Sie das NumberFormatInfo Objekt in Clientanwendungen zum Formatieren und Analysieren von Benutzereingaben oder zum Anzeigen numerischer Daten verwenden. Für Serveranwendungen oder unbeaufsichtigte Anwendungen sollten Sie Benutzereinstellungen nicht berücksichtigen. Wenn Sie das NumberFormatInfo Objekt jedoch explizit oder implizit zum Speichern numerischer Daten in Zeichenfolgenform verwenden, sollten Sie entweder ein NumberFormatInfo Objekt verwenden, das die Formatierungskonventionen der invarianten Kultur widerspiegelt, oder Sie sollten eine benutzerdefinierte zahlenformatische Zeichenfolge angeben, die Sie unabhängig von der Kultur verwenden.

IFormatProvider, NumberFormatInfo und numerische Formatierung

Ein NumberFormatInfo Objekt wird implizit oder explizit in allen numerischen Formatierungsvorgängen verwendet. Dazu gehören Aufrufe der folgenden Methoden:

Alle numerischen Formatierungsvorgänge verwenden eine IFormatProvider Implementierung. Die IFormatProvider Schnittstelle enthält eine einzelne Methode, GetFormat(Type). Dies ist eine Rückrufmethode, der ein Type Objekt übergeben wird, das den Typ darstellt, der zum Bereitstellen von Formatierungsinformationen erforderlich ist. Die Methode ist dafür verantwortlich, entweder eine Instanz dieses Typs oder null zurückzugeben, wenn sie keine Instanz des Typs bereitstellen kann. .NET stellt zwei IFormatProvider Implementierungen zum Formatieren von Zahlen bereit:

Wenn eine IFormatProvider Implementierung nicht explizit für eine Formatierungsmethode bereitgestellt wird, wird ein CultureInfo von der CultureInfo.CurrentCulture Eigenschaft zurückgegebenes Objekt verwendet, das die aktuelle Kultur darstellt.

Im folgenden Beispiel wird die Beziehung zwischen der IFormatProvider Schnittstelle und der NumberFormatInfo Klasse in Formatierungsvorgängen veranschaulicht, indem eine benutzerdefinierte IFormatProvider Implementierung definiert wird. Die GetFormat Methode zeigt den Typnamen des Objekts an, das vom Formatierungsvorgang angefordert wird. Wenn die Schnittstelle ein NumberFormatInfo Objekt anfordert, stellt diese Methode das NumberFormatInfo Objekt für die aktuelle Kultur bereit. Wie die Ausgabe des Beispiels zeigt, fordert die Decimal.ToString(IFormatProvider) Methode ein NumberFormatInfo Objekt an, um Formatierungsinformationen bereitzustellen, während die String.Format(IFormatProvider, String, Object[]) Methode NumberFormatInfo und DateTimeFormatInfo Objekte sowie eine ICustomFormatter Implementierung anfordert.

using System;
using System.Globalization;

public class CurrentCultureFormatProvider : IFormatProvider
{
    public Object GetFormat(Type formatType)
    {
        Console.WriteLine($"Requesting an object of type {formatType.Name}");
        if (formatType == typeof(NumberFormatInfo))
            return NumberFormatInfo.CurrentInfo;
        else if (formatType == typeof(DateTimeFormatInfo))
            return DateTimeFormatInfo.CurrentInfo;
        else
            return null;
    }
}

public class FormatProviderEx
{
    public static void Main()
    {
        Decimal amount = 1203.541m;
        string value = amount.ToString("C2", new CurrentCultureFormatProvider());
        Console.WriteLine(value);
        Console.WriteLine();
        string composite = String.Format(new CurrentCultureFormatProvider(),
                                         "Date: {0}   Amount: {1}   Description: {2}",
                                         DateTime.Now, 1264.03m, "Service Charge");
        Console.WriteLine(composite);
        Console.WriteLine();
    }
}
// The example displays output like the following:
//    Requesting an object of type NumberFormatInfo
//    $1,203.54
//
//    Requesting an object of type ICustomFormatter
//    Requesting an object of type DateTimeFormatInfo
//    Requesting an object of type NumberFormatInfo
//    Date: 11/15/2012 2:00:01 PM   Amount: 1264.03   Description: Service Charge

Wenn eine Implementierung nicht explizit in einem Aufruf einer IFormatProvider numerischen Formatierungsmethode bereitgestellt wird, ruft die Methode die CultureInfo.CurrentCulture.GetFormat Methode auf, die das NumberFormatInfo Objekt zurückgibt, das der aktuellen Kultur entspricht.

Formatzeichenfolgen und NumberFormatInfo-Eigenschaften

Jeder Formatierungsvorgang verwendet entweder eine Standard- oder eine benutzerdefinierte numerische Formatzeichenfolge, um eine Ergebniszeichenfolge aus einer Zahl zu erzeugen. In einigen Fällen ist die Verwendung einer Formatzeichenfolge zum Erzeugen einer Ergebniszeichenfolge explizit, wie im folgenden Beispiel gezeigt. Dieser Code ruft die Decimal.ToString(IFormatProvider) Methode auf, um einen Decimal Wert in eine Reihe verschiedener Zeichenfolgendarstellungen mithilfe der Formatierungskonventionen der en-US Kultur zu konvertieren.

using System;
using System.Globalization;

public class PropertiesEx1
{
    public static void Main()
    {
        string[] formatStrings = { "C2", "E1", "F", "G3", "N",
                                 "#,##0.000", "0,000,000,000.0##" };
        CultureInfo culture = CultureInfo.CreateSpecificCulture("en-US");
        Decimal[] values = { 1345.6538m, 1921651.16m };

        foreach (var value in values)
        {
            foreach (var formatString in formatStrings)
            {
                string resultString = value.ToString(formatString, culture);
                Console.WriteLine("{0,-18} -->  {1}", formatString, resultString);
            }
            Console.WriteLine();
        }
    }
}
// The example displays the following output:
//       C2                 -->  $1,345.65
//       E1                 -->  1.3E+003
//       F                  -->  1345.65
//       G3                 -->  1.35E+03
//       N                  -->  1,345.65
//       #,##0.000          -->  1,345.654
//       0,000,000,000.0##  -->  0,000,001,345.654
//
//       C2                 -->  $1,921,651.16
//       E1                 -->  1.9E+006
//       F                  -->  1921651.16
//       G3                 -->  1.92E+06
//       N                  -->  1,921,651.16
//       #,##0.000          -->  1,921,651.160
//       0,000,000,000.0##  -->  0,001,921,651.16

In anderen Fällen ist die Verwendung einer Formatzeichenfolge implizit. Bei den folgenden Methodenaufrufen an die Standard- oder parameterlose Decimal.ToString() Methode wird beispielsweise der Wert der Decimal Instanz mithilfe des allgemeinen ("G")-Formatbezeichners und der Konventionen der aktuellen Kultur formatiert, die in diesem Fall die en-US Kultur ist.

using System;

public class PropertiesEx2
{
    public static void Main()
    {
        Decimal[] values = { 1345.6538m, 1921651.16m };

        foreach (var value in values)
        {
            string resultString = value.ToString();
            Console.WriteLine(resultString);
            Console.WriteLine();
        }
    }
}
// The example displays the following output:
//       1345.6538
//
//       1921651.16

Jede standardmäßige numerische Formatzeichenfolge verwendet eine oder NumberFormatInfo mehrere Eigenschaften, um das Muster oder die symbole zu bestimmen, die in der Ergebniszeichenfolge verwendet werden. Entsprechend fügen alle benutzerdefinierten Zahlenformatbezeichner außer "0" und "#" Symbole in die Ergebniszeichenfolge ein, die durch NumberFormatInfo Eigenschaften definiert sind. In der folgenden Tabelle sind die Standard- und benutzerdefinierten Zahlenformatbezeichner und die zugehörigen NumberFormatInfo Eigenschaften aufgeführt. Informationen zum Ändern der Darstellung der Ergebniszeichenfolge für eine bestimmte Kultur finden Sie im Abschnitt Eigenschaften von NumberFormatInfo ändern. Ausführliche Informationen zur Verwendung dieser Formatbezeichner finden Sie unter "Standard Numeric Format Strings " und "Custom Numeric Format Strings".

Formatbezeichner Zugeordnete Eigenschaften
„C“ oder „c“ (Spezifizierer für das Währungsformat) CurrencyDecimalDigits zur Definition der Standardanzahl von Dezimalstellen.

CurrencyDecimalSeparator, um das Dezimaltrennzeichen zu definieren.

CurrencyGroupSeparator zur Definition des Gruppen- oder Tausendertrennzeichens.

CurrencyGroupSizes, um die Größen von integralen Gruppen zu definieren.

CurrencyNegativePattern, um das Muster negativer Währungswerte zu definieren.

CurrencyPositivePattern, um das Muster positiver Währungswerte zu definieren.

CurrencySymbol, um das Währungssymbol zu definieren.

NegativeSign, um das Negative Zeichensymbol zu definieren.
„D“ oder „d“ (Spezifizierer für das Dezimalformat) NegativeSign, um das Negative Zeichensymbol zu definieren.
„E“ oder „e“ (Spezifizierer für das exponentielle oder wissenschaftlicher Format) NegativeSign zur Definition des Symbols für das negative Vorzeichen in der Mantisse und im Exponenten.

NumberDecimalSeparator, um das Dezimaltrennzeichen zu definieren.

PositiveSign zur Definition des Symbols für das positive Vorzeichen in der Mantisse und im Exponenten.
„F“ oder „f“ (Spezifizierer für Festkommaformat) NegativeSign, um das Negative Zeichensymbol zu definieren.

NumberDecimalDigits zur Definition der Standardanzahl von Dezimalstellen.

NumberDecimalSeparator, um das Dezimaltrennzeichen zu definieren.
„G“ oder „g“ (Spezifizierer für das allgemeine Format) NegativeSign, um das Negative Zeichensymbol zu definieren.

NumberDecimalSeparator, um das Dezimaltrennzeichen zu definieren.

PositiveSign, um das positive Zeichensymbol für Ergebniszeichenfolgen im exponentiellen Format zu definieren.
„N“ oder „n“ (Spezifizierer für das numerische Format) NegativeSign, um das Negative Zeichensymbol zu definieren.

NumberDecimalDigits zur Definition der Standardanzahl von Dezimalstellen.

NumberDecimalSeparator, um das Dezimaltrennzeichen zu definieren.

NumberGroupSeparator zur Definition des Gruppentrennzeichens (Tausender).

NumberGroupSizes, um die Anzahl der integralen Ziffern in einer Gruppe zu definieren.

NumberNegativePattern, um das Format negativer Werte zu definieren.
„P“ oder „p“ (Spezifizierer für das Prozentformat) NegativeSign, um das Negative Zeichensymbol zu definieren.

PercentDecimalDigits zur Definition der Standardanzahl von Dezimalstellen.

PercentDecimalSeparator, um das Dezimaltrennzeichen zu definieren.

PercentGroupSeparator, um das Gruppentrennzeichen zu definieren.

PercentGroupSizes, um die Anzahl der integralen Ziffern in einer Gruppe zu definieren.

PercentNegativePattern, um die Platzierung des Prozentsymbols und das negative Symbol für negative Werte zu definieren.

PercentPositivePattern, um die Platzierung des Prozentsymbols für positive Werte zu definieren.

PercentSymbol, um das Prozentsymbol zu definieren.
„R“ oder „r“ (Spezifizierer für das Roundtripformat) NegativeSign, um das Negative Zeichensymbol zu definieren.

NumberDecimalSeparator, um das Dezimaltrennzeichen zu definieren.

PositiveSign, um das positive Zeichensymbol in einem Exponenten zu definieren.
„H“ oder „h“ (Spezifizierer für das Hexadezimalformat) Keiner.
„.“ (benutzerdefinierter Spezifizierer für das Dezimaltrennzeichen) NumberDecimalSeparator, um das Dezimaltrennzeichen zu definieren.
„,“ (benutzerdefinierter Spezifizierer für das Gruppentrennzeichen) NumberGroupSeparator zur Definition des Gruppentrennzeichens (Tausender).
„%“ (benutzerdefinierter Spezifizierer für den Prozentplatzhalter) PercentSymbol, um das Prozentsymbol zu definieren.
„‰“ (benutzerdefinierter Spezifizierer für den Tausenderplatzhalter) PerMilleSymbol, um das Promillezeichen zu definieren.
"E" (benutzerdefinierter Formatbezeichner für Exponentialschreibweise) NegativeSign zur Definition des Symbols für das negative Vorzeichen in der Mantisse und im Exponenten.

PositiveSign zur Definition des Symbols für das positive Vorzeichen in der Mantisse und im Exponenten.

Beachten Sie, dass die NumberFormatInfo Klasse eine NativeDigits Eigenschaft enthält, die die basis 10 Ziffern angibt, die von einer bestimmten Kultur verwendet werden. Die Eigenschaft wird jedoch nicht in Formatierungsvorgängen verwendet; Nur die einfachen lateinischen Ziffern 0 (U+0030) bis 9 (U+0039) werden in der Ergebniszeichenfolge verwendet. Die Ergebniszeichenfolge besteht zusätzlich für die Werte von Single, Double, NaN, PositiveInfinity und NegativeInfinity ausschließlich aus den durch die Eigenschaften NaNSymbol, PositiveInfinitySymbol und NegativeInfinitySymbol definierten Symbolen.

Ändern von NumberFormatInfo-Eigenschaften

Sie können die Eigenschaften eines NumberFormatInfo Objekts ändern, um die ergebniszeichenfolge anzupassen, die in einem numerischen Formatierungsvorgang erzeugt wird. Um dies zu tun:

  1. Erstellen Sie eine Lese-/Schreibkopie eines NumberFormatInfo Objekts, dessen Formatierungskonventionen Sie ändern möchten. Weitere Informationen finden Sie im Abschnitt "Instanziieren eines NumberFormatInfo-Objekts ".

  2. Ändern Sie die Eigenschaft oder Eigenschaften, die verwendet werden, um die gewünschte Ergebniszeichenfolge zu erzeugen. Informationen dazu, wie Formatierungsmethoden NumberFormatInfo Eigenschaften zum Definieren von Ergebniszeichenfolgen verwenden, finden Sie im Abschnitt "Formatzeichenfolgen und NumberFormatInfo-Eigenschaften".

  3. Verwenden Sie das benutzerdefinierte NumberFormatInfo Objekt als IFormatProvider Argument in Aufrufen von Formatierungsmethoden.

Hinweis

Anstatt die Eigenschaftswerte einer Kultur bei jedem Start einer Anwendung dynamisch zu ändern, können Sie die CultureAndRegionInfoBuilder Klasse verwenden, um entweder eine benutzerdefinierte Kultur (eine Kultur mit einem eindeutigen Namen und die vorhandene Kulturen ergänzt) oder eine Ersetzungskultur (eine kultur, die anstelle einer bestimmten Kultur verwendet wird) zu definieren.

Die folgenden Abschnitte enthalten einige Beispiele.

Ändern des Währungssymbols und -musters

Im folgenden Beispiel wird ein NumberFormatInfo Objekt geändert, das die Formatierungskonventionen der en-US Kultur darstellt. Es weist der CurrencySymbol Eigenschaft das ISO-4217-Währungssymbol zu und definiert ein Muster für Währungswerte, das aus dem Währungssymbol gefolgt von einem Leerzeichen und einem numerischen Wert besteht.

using System;
using System.Globalization;

public class Example
{
    public static void Main()
    {
        // Retrieve a writable NumberFormatInfo object.
        CultureInfo enUS = CultureInfo.CreateSpecificCulture("en-US");
        NumberFormatInfo nfi = enUS.NumberFormat;

        // Use the ISO currency symbol instead of the native currency symbol.
        nfi.CurrencySymbol = (new RegionInfo(enUS.Name)).ISOCurrencySymbol;
        // Change the positive currency pattern to <code><space><value>.
        nfi.CurrencyPositivePattern = 2;
        // Change the negative currency pattern to <code><space><sign><value>.
        nfi.CurrencyNegativePattern = 12;

        // Produce the result strings by calling ToString.
        Decimal[] values = { 1065.23m, 19.89m, -.03m, -175902.32m };
        foreach (var value in values)
            Console.WriteLine(value.ToString("C", enUS));

        Console.WriteLine();

        // Produce the result strings by calling a composite formatting method.
        foreach (var value in values)
            Console.WriteLine(String.Format(enUS, "{0:C}", value));
    }
}
// The example displays the following output:
//       USD 1,065.23
//       USD 19.89
//       USD -0.03
//       USD -175,902.32
//
//       USD 1,065.23
//       USD 19.89
//       USD -0.03
//       USD -175,902.32

Formatieren einer nationalen Identifikationsnummer

Viele nationale Identifikationsnummern bestehen ausschließlich aus Ziffern und können so einfach formatiert werden, indem die Eigenschaften eines NumberFormatInfo Objekts geändert werden. Eine Sozialversicherungsnummer in den USA besteht beispielsweise aus 9 Ziffern, die wie folgt angeordnet sind: XXX-XX-XXXX Im folgenden Beispiel wird davon ausgegangen, dass Sozialversicherungsnummern als ganzzahlige Werte gespeichert und entsprechend formatiert werden.

using System;
using System.Globalization;

public class CustomizeSSNEx
{
    public static void Main()
    {
        // Instantiate a read-only NumberFormatInfo object.
        CultureInfo enUS = CultureInfo.CreateSpecificCulture("en-US");
        NumberFormatInfo nfi = enUS.NumberFormat;

        // Modify the relevant properties.
        nfi.NumberGroupSeparator = "-";
        nfi.NumberGroupSizes = new int[] { 3, 2, 4 };
        nfi.NumberDecimalDigits = 0;

        int[] ids = { 111223333, 999776666 };

        // Produce the result string by calling ToString.
        foreach (var id in ids)
            Console.WriteLine(id.ToString("N", enUS));

        Console.WriteLine();

        // Produce the result string using composite formatting.
        foreach (var id in ids)
            Console.WriteLine(String.Format(enUS, "{0:N}", id));
    }
}
// The example displays the following output:
//       1112-23-333
//       9997-76-666
//
//       1112-23-333
//       9997-76-666

Analysieren numerischer Zeichenfolgen

Die Analyse umfasst das Konvertieren der Zeichenfolgendarstellung einer Zahl in eine Zahl. Jeder numerische Typ in .NET enthält zwei überladene Analysemethoden: Parse und TryParse. Die Parse Methode konvertiert eine Zeichenfolge in eine Zahl und löst eine Ausnahme aus, wenn die Konvertierung fehlschlägt. Die TryParse Methode konvertiert eine Zeichenfolge in eine Zahl, weist die Zahl einem out Argument zu und gibt einen Boolean Wert zurück, der angibt, ob die Konvertierung erfolgreich war.

Die Analysemethoden können implizit oder explizit einen NumberStyles Enumerationswert verwenden, um zu bestimmen, welche Stilelemente (z. B. Gruppentrennzeichen, ein Dezimaltrennzeichen oder ein Währungssymbol) in einer Zeichenfolge vorhanden sein können, wenn der Analysevorgang erfolgreich ist. Wenn im NumberStyles-Methodenaufruf kein Wert angegeben wird, ist der Standardwert ein NumberStyles-Wert, der die Flags Float und AllowThousands enthält und angibt, dass die analysierte Zeichenfolge Gruppensymbole, ein Dezimaltrennzeichen, ein negatives Vorzeichen und Leerzeichen enthalten kann oder dass es sich um die Zeichenfolgendarstellung einer Zahl in exponentieller Schreibweise handeln kann.

Die Analysemethoden verwenden auch implizit oder explizit ein NumberFormatInfo Objekt, das die spezifischen Symbole und Muster definiert, die in der zu analysierenden Zeichenfolge auftreten können. Wenn kein NumberFormatInfo-Objekt angegeben wird, ist der Standardwert das NumberFormatInfo für die aktuelle Kultur. Weitere Informationen zur Analyse finden Sie in den einzelnen Analysemethoden, wie z. B. Int16.Parse(String), Int32.Parse(String, NumberStyles), Int64.Parse(String, IFormatProvider), Decimal.Parse(String, NumberStyles, IFormatProvider), Double.TryParse(String, Double) und BigInteger.TryParse(String, NumberStyles, IFormatProvider, BigInteger).

Im folgenden Beispiel wird die kultursensible Art und Weise der Analyse von Zeichenfolgen veranschaulicht. Es wird versucht, eine Zeichenfolge zu analysieren, die Tausendertrennzeichen enthält, indem die Konventionen der Kulturen „en-US“, „fr-FR“ und „invariant“ verwendet werden. Eine Zeichenfolge, die ein Komma als Gruppentrennzeichen und einen Punkt als Dezimaltrennzeichen enthält, kann in der Kultur „fr-FR“ nicht analysiert werden kann, und eine Zeichenfolge mit einem Leerzeichen als Gruppentrennzeichen und einem Komma als Dezimaltrennzeichen kann in den Kulturen „en-US“ und „invariant“ nicht analysiert werden.

using System;
using System.Globalization;

public class ParseEx1
{
    public static void Main()
    {
        String[] values = { "1,034,562.91", "9 532 978,07" };
        String[] cultureNames = { "en-US", "fr-FR", "" };

        foreach (var value in values)
        {
            foreach (var cultureName in cultureNames)
            {
                CultureInfo culture = CultureInfo.CreateSpecificCulture(cultureName);
                String name = culture.Name == "" ? "Invariant" : culture.Name;
                try
                {
                    Decimal amount = Decimal.Parse(value, culture);
                    Console.WriteLine($"'{value}' --> {amount} ({name})");
                }
                catch (FormatException)
                {
                    Console.WriteLine($"'{value}': FormatException ({name})");
                }
            }
            Console.WriteLine();
        }
    }
}
// The example displays the following output:
//       '1,034,562.91' --> 1034562.91 (en-US)
//       '1,034,562.91': FormatException (fr-FR)
//       '1,034,562.91' --> 1034562.91 (Invariant)
//
//       '9 532 978,07': FormatException (en-US)
//       '9 532 978,07' --> 9532978.07 (fr-FR)
//       '9 532 978,07': FormatException (Invariant)

Die Analyse erfolgt in der Regel in zwei Kontexten:

  • Als Vorgang, der zum Konvertieren von Benutzereingaben in einen numerischen Wert konzipiert ist.

  • Als Vorgang, der als Roundtrip-Vorgang für einen numerischen Wert konzipiert ist; d. h., um einen numerischen Wert zu deserialisieren, der zuvor als Zeichenfolge serialisiert wurde.

In den folgenden Abschnitten werden diese beiden Vorgänge ausführlicher erläutert.

Analysieren von Benutzerzeichenfolgen

Wenn Sie vom Benutzer eingegebene numerische Zeichenfolgen analysieren, sollten Sie immer ein NumberFormatInfo Objekt instanziieren, das die kulturellen Einstellungen des Benutzers widerspiegelt. Informationen zum Instanziieren eines NumberFormatInfo Objekts, das Benutzeranpassungen widerspiegelt, finden Sie im Abschnitt "Dynamische Daten ".

Das folgende Beispiel veranschaulicht den Unterschied zwischen einem Analysevorgang, der benutzerkulturelle Einstellungen widerspiegelt und die nicht. In diesem Fall ist die Standardsystemkultur en-US, aber der Benutzer hat "," als Dezimalsymbol und "." als Gruppentrennzeichen in der Systemsteuerung, Region und Sprache definiert. Normalerweise werden diese Symbole in der Standardkultur en-US umgekehrt. Wenn der Benutzer eine Zeichenfolge eingibt, die Benutzereinstellungen widerspiegelt und die Zeichenfolge von einem NumberFormatInfo Objekt analysiert wird, das auch Benutzereinstellungen (Außerkraftsetzungen) widerspiegelt, gibt der Analysevorgang ein richtiges Ergebnis zurück. Wenn die Zeichenfolge jedoch von einem NumberFormatInfo-Objekt analysiert wird, das Standardeinstellungen für die Kultur „en-US“ widerspiegelt, ist das Kommasymbol als Gruppentrennzeichen falsch und gibt ein falsches Ergebnis zurück.

using System;
using System.Globalization;

public class ParseUserEx
{
    public static void Main()
    {
        CultureInfo stdCulture = CultureInfo.GetCultureInfo("en-US");
        CultureInfo custCulture = CultureInfo.CreateSpecificCulture("en-US");

        String value = "310,16";
        try
        {
            Console.WriteLine($"{stdCulture.Name} culture reflects user overrides: {stdCulture.UseUserOverride}");
            Decimal amount = Decimal.Parse(value, stdCulture);
            Console.WriteLine($"'{value}' --> {amount.ToString(CultureInfo.InvariantCulture)}");
        }
        catch (FormatException)
        {
            Console.WriteLine($"Unable to parse '{value}'");
        }
        Console.WriteLine();

        try
        {
            Console.WriteLine($"{custCulture.Name} culture reflects user overrides: {custCulture.UseUserOverride}");
            Decimal amount = Decimal.Parse(value, custCulture);
            Console.WriteLine($"'{value}' --> {amount.ToString(CultureInfo.InvariantCulture)}");
        }
        catch (FormatException)
        {
            Console.WriteLine($"Unable to parse '{value}'");
        }
    }
}
// The example displays the following output:
//       en-US culture reflects user overrides: False
//       '310,16' --> 31016
//
//       en-US culture reflects user overrides: True
//       '310,16' --> 310.16

Serialisieren und Deserialisieren numerischer Daten

Wenn numerische Daten im Zeichenfolgenformat serialisiert und später deserialisiert und analysiert werden, sollten die Zeichenfolgen mithilfe der Konventionen der invarianten Kultur generiert und analysiert werden. Die Formatierungs- und Analysevorgänge sollten niemals die Konventionen einer bestimmten Kultur widerspiegeln. Wenn kulturspezifische Einstellungen verwendet werden, ist die Portabilität der Daten streng begrenzt; sie kann nur auf einem Thread, dessen kulturspezifische Einstellungen mit denen des Threads identisch sind, auf dem sie serialisiert wurde, erfolgreich deserialisiert werden. In einigen Fällen bedeutet dies, dass die Daten nicht einmal erfolgreich auf demselben System deserialisiert werden können, auf dem sie serialisiert wurde.

Das folgende Beispiel veranschaulicht, was passieren kann, wenn dieses Prinzip verletzt wird. Gleitkommawerte in einem Array werden in Zeichenfolgen konvertiert, wenn der aktuelle Thread die kulturspezifischen Einstellungen der Kultur „en-US“ verwendet. Die Daten werden dann von einem Thread analysiert, der die kulturspezifischen Einstellungen der pt-BR Kultur verwendet. In diesem Fall wird zwar jeder Analysevorgang erfolgreich durchgeführt, jedoch gelingt die Rückübertragung der Daten nicht, und es kommt zu Datenbeschädigungen. In anderen Fällen kann ein Analysevorgang fehlschlagen und eine FormatException Ausnahme ausgelöst werden.

using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Threading;

public class ParsePersistedEx
{
    public static void Main()
    {
        CultureInfo.CurrentCulture = CultureInfo.CreateSpecificCulture("en-US");
        PersistData();

        CultureInfo.CurrentCulture = CultureInfo.CreateSpecificCulture("pt-BR");
        RestoreData();
    }

    private static void PersistData()
    {
        // Define an array of floating-point values.
        Double[] values = { 160325.972, 8631.16, 1.304e5, 98017554.385,
                          8.5938287084321676e94 };
        Console.WriteLine("Original values: ");
        foreach (var value in values)
            Console.WriteLine(value.ToString("R", CultureInfo.InvariantCulture));

        // Serialize an array of doubles to a file
        StreamWriter sw = new StreamWriter(@".\NumericData.bin");
        for (int ctr = 0; ctr < values.Length; ctr++)
        {
            sw.Write(values[ctr].ToString("R"));
            if (ctr < values.Length - 1) sw.Write("|");
        }
        sw.Close();
        Console.WriteLine();
    }

    private static void RestoreData()
    {
        // Deserialize the data
        StreamReader sr = new StreamReader(@".\NumericData.bin");
        String data = sr.ReadToEnd();
        sr.Close();

        String[] stringValues = data.Split('|');
        List<Double> newValueList = new List<Double>();

        foreach (var stringValue in stringValues)
        {
            try
            {
                newValueList.Add(Double.Parse(stringValue));
            }
            catch (FormatException)
            {
                newValueList.Add(Double.NaN);
            }
        }

        Console.WriteLine("Restored values:");
        foreach (var newValue in newValueList)
            Console.WriteLine(newValue.ToString("R", NumberFormatInfo.InvariantInfo));
    }
}
// The example displays the following output:
//       Original values:
//       160325.972
//       8631.16
//       130400
//       98017554.385
//       8.5938287084321671E+94
//
//       Restored values:
//       160325972
//       863116
//       130400
//       98017554385
//       8.5938287084321666E+110