Formatieren von Typen in .NET

Bei der Formatierung wird eine Instanz einer Klasse, Struktur oder eines Enumerationswerts in die entsprechende Zeichenfolgendarstellung konvertiert. Die resultierende Zeichenfolge kann dann häufig Benutzern angezeigt oder sie kann deserialisiert werden, um den ursprünglichen Datentyp wiederherzustellen. Diese Konvertierung kann eine Reihe von Problemen beinhalten:

  • Die Art, wie diese Werte intern gespeichert werden, spiegelt nicht notwendigerweise die Art wider, wie die Benutzer sie anzeigen möchten. Eine Telefonnummer könnte beispielsweise wie folgt gespeichert werden: 8009999999. Dies ist jedoch wenig benutzerfreundlich. Stattdessen sollte die Telefonnummer wie folgt angezeigt werden: 800-999-9999. Ein Beispiel für die Formatierung einer Zahl auf diese Weise finden Sie im Abschnitt Benutzerdefinierte Formatzeichenfolgen .

  • Manchmal ist die Konvertierung eines Objekts in seine Zeichenfolgendarstellung nicht intuitiv. Beispielsweise ist nicht klar, wie die Zeichenfolgendarstellung eines Temperature-Objekts oder eines Person-Objekts aussehen sollte. Ein Beispiel für die Formatierung eines Temperature-Objekts auf verschiedene Weise finden Sie im Abschnitt Standardformatzeichenfolgen .

  • Oft ist für Werte eine kulturabhängige Formatierung erforderlich. In einer Anwendung, die zum Darstellen von Währungswerten Zahlen verwendet, sollten numerische Zeichenfolgen beispielsweise das Währungssymbol der aktuellen Kultur, das Gruppentrennzeichen (in den meisten Kulturen das Tausendertrennzeichen) und das Dezimaltrennzeichen einschließen. Ein Beispiel finden Sie im Abschnitt Kulturabhängige Formatierung mit Formatanbietern.

  • Unter Umständen muss ein Wert in einer Anwendung auf unterschiedliche Arten angezeigt werden. Beispielsweise stellt eine Anwendung einen Enumerationsmember möglicherweise dar, indem eine Zeichenfolgendarstellung des Namens oder des zugrunde liegende Werts angezeigt wird. Ein Beispiel für die Formatierung eines Members der DayOfWeek -Enumeration auf unterschiedliche Weise finden Sie im Abschnitt Standardformatzeichenfolgen .

Hinweis

Durch das Formatieren wird der Wert eines Typs in eine Zeichenfolgendarstellung konvertiert. Die Analyse ist die Umkehroperation zum Formatieren. In einem Analysevorgang wird eine Instanz eines Datentyps aus seiner Zeichenfolgendarstellung erstellt. Informationen zum Konvertieren von Zeichenfolgen in andere Datentypen finden Sie unter Analysieren von Zeichenfolgen in .NET.

.NET bietet eine umfangreiche Formatierungsunterstützung, die es Entwicklern ermöglicht, diese Anforderungen zu erfüllen.

Formatierung in .NET

Der grundlegende Mechanismus für die Formatierung ist die Standardimplementierung der Object.ToString-Methode, die im Abschnitt Standardformatierung mit der ToString-Methode später in diesem Thema erläutert wird. .NET bietet jedoch mehrere Möglichkeiten, die Standardformatierungsunterstützung zu ändern und zu erweitern. Hierzu gehört Folgendes:

  • Überschreiben der Object.ToString-Methode, um eine benutzerdefinierte Zeichenfolgendarstellung für den Wert eines Objekts zu definieren. Weitere Informationen erhalten Sie im Abschnitt Überschreiben der ToString-Methode weiter unten in diesem Thema.

  • Definieren von Formatbezeichnern, die es ermöglichen, dass die Zeichenfolgendarstellung des Werts eines Objekts mehrere Formate annehmen kann. Der Formatbezeichner "X" in der folgenden Anweisung konvertiert beispielsweise eine ganze Zahl in die Zeichenfolgendarstellung eines Hexadezimalwerts.

    int integerValue = 60312;
    Console.WriteLine(integerValue.ToString("X"));   // Displays EB98.
    
    Dim integerValue As Integer = 60312
    Console.WriteLine(integerValue.ToString("X"))   ' Displays EB98.
    

    Weitere Informationen zu Formatbezeichnern finden Sie im Abschnitt ToString-Methode und Formatzeichenfolgen .

  • Verwenden von Formatanbietern, die Formatierungskonventionen einer bestimmten Kultur nutzen. Beispielsweise zeigt die folgende Anweisung einen Währungswert unter Verwendung der Formatierungskonventionen der Kultur en-US an.

    double cost = 1632.54;
    Console.WriteLine(cost.ToString("C",
                      new System.Globalization.CultureInfo("en-US")));
    // The example displays the following output:
    //       $1,632.54
    
    Dim cost As Double = 1632.54
    Console.WriteLine(cost.ToString("C", New System.Globalization.CultureInfo("en-US")))
    ' The example displays the following output:
    '       $1,632.54
    

    Weitere Informationen zum Formatieren mit Formatanbietern finden Sie im Abschnitt Formatanbieter.

  • Implementieren der IFormattable -Schnittstelle zur Unterstützung der Zeichenfolgenkonvertierung mit der Convert -Klasse sowie der kombinierten Formatierung. Weitere Informationen finden Sie im Abschnitt IFormattable-Schnittstelle .

  • Verwenden der kombinierten Formatierung, um die Zeichenfolgendarstellung eines Werts in einer größeren Zeichenfolge einzubetten. Weitere Informationen finden Sie im Abschnitt Kombinierte Formatierung .

  • Implementieren von ICustomFormatter und IFormatProvider , um eine vollständige benutzerdefinierte Formatierungslösung bereitzustellen. Weitere Informationen finden Sie im Abschnitt Benutzerdefinierte Formatierung mit ICustomFormatter .

In den folgenden Abschnitten werden diese Methoden zum Konvertieren eines Objekts in seine Zeichenfolgendarstellung ausführlicher erläutert.

Standardformatierung mit der ToString-Methode

Jeder von System.Object abgeleitete Typ erbt automatisch eine parameterlose ToString -Methode, die standardmäßig den Namen des Typs zurückgibt. Das folgende Beispiel veranschaulicht die ToString -Standardmethode. Dabei wird eine Klasse mit dem Namen Automobile ohne Implementierung definiert. Wenn die Klasse instanziiert und die zugehörige ToString -Methode aufgerufen wird, wird der Typname angezeigt. Beachten Sie, dass die ToString -Methode im Beispiel nicht explizit aufgerufen wird. Die Console.WriteLine(Object) -Methode ruft implizit die ToString -Methode des Objekts auf, das ihr als Argument übergeben wird.

using System;

public class Automobile
{
   // No implementation. All members are inherited from Object.
}

public class Example9
{
   public static void Main()
   {
      Automobile firstAuto = new Automobile();
      Console.WriteLine(firstAuto);
   }
}
// The example displays the following output:
//       Automobile
Public Class Automobile
    ' No implementation. All members are inherited from Object.
End Class

Module Example9
    Public Sub Main9()
        Dim firstAuto As New Automobile()
        Console.WriteLine(firstAuto)
    End Sub
End Module
' The example displays the following output:
'       Automobile

Warnung

Ab Windows 8.1 enthält die Windows-Runtime eine Schnittstelle IStringable mit einer einzelnen Methode, IStringable.ToString, die eine standardmäßige Formatierungsunterstützung bereitstellt. Es wird jedoch empfohlen, dass verwaltete Typen die IStringable -Schnittstelle nicht implementieren. Weitere Informationen finden Sie im Abschnitt „Die Windows-Runtime und die IStringable-Schnittstelle“ auf der Object.ToString-Referenzseite.

Da alle anderen Typen außer Schnittstellen von Objectabgeleitet werden, wird diese Funktionalität automatisch für die benutzerdefinierten Klassen oder Strukturen bereitgestellt. Aber die von der standardmäßigen ToString-Methode gebotene Funktionalität ist beschränkt: Zwar identifiziert sie den Typ, liefert jedoch keine Informationen zu einer Instanz des Typs. Um eine Zeichenfolgendarstellung eines Objekts bereitzustellen, die Informationen zum Objekt enthält, müssen Sie die ToString -Methode überschreiben.

Hinweis

Strukturen erben vom ValueType, der von Objectabgeleitet wird. Auch wenn ValueType von Object.ToStringüberschrieben wird, ist die Implementierung identisch.

Überschreiben der ToString-Methode

Das Anzeigen des Namens eines Typs ist oft nur von geringem Nutzen und ermöglicht Consumern der Typen keine Unterscheidung zwischen den einzelnen Instanzen. Sie können jedoch die ToString-Methode überschreiben, um eine nützlichere Darstellung eines Objektwerts bereitzustellen. Im folgenden Beispiel wird ein Temperature -Objekt definiert und die ToString -Methode wird überschrieben, um die Temperatur in Grad Celsius anzuzeigen.

public class Temperature
{
    private decimal temp;

    public Temperature(decimal temperature)
    {
        this.temp = temperature;
    }

    public override string ToString()
    {
        return this.temp.ToString("N1") + "°C";
    }
}

public class Example12
{
    public static void Main()
    {
        Temperature currentTemperature = new Temperature(23.6m);
        Console.WriteLine($"The current temperature is {currentTemperature}");
    }
}
// The example displays the following output:
//       The current temperature is 23.6°C.
Public Class Temperature
    Private temp As Decimal

    Public Sub New(temperature As Decimal)
        Me.temp = temperature
    End Sub

    Public Overrides Function ToString() As String
        Return Me.temp.ToString("N1") + "°C"
    End Function
End Class

Module Example13
    Public Sub Main13()
        Dim currentTemperature As New Temperature(23.6D)
        Console.WriteLine("The current temperature is " +
                          currentTemperature.ToString())
    End Sub
End Module
' The example displays the following output:
'       The current temperature is 23.6°C.

In .NET wurde die ToString-Methode jedes primitiven Werttyps überschrieben, um den Wert des Objekts statt seines Namens anzuzeigen. In der folgenden Tabelle wird die Überschreibung für den jeweiligen primitiven Typ angezeigt. Beachten Sie, dass die meisten der überschriebenen Methoden eine andere Überladung der ToString -Methode aufrufen und dabei den Formatbezeichner G übergeben, der das allgemeine Format des Typs definiert, sowie ein IFormatProvider -Objekt, das die aktuelle Kultur darstellt.

Typ ToString-Überschreibung
Boolean Gibt entweder Boolean.TrueString oder Boolean.FalseStringzurück.
Byte Ruft Byte.ToString("G", NumberFormatInfo.CurrentInfo) auf, um den Byte -Wert für die aktuelle Kultur zu formatieren.
Char Gibt das Zeichen als Zeichenfolge zurück.
DateTime Ruft DateTime.ToString("G", DatetimeFormatInfo.CurrentInfo) auf, um den Datums- und Uhrzeitwert für die aktuelle Kultur zu formatieren.
Decimal Ruft Decimal.ToString("G", NumberFormatInfo.CurrentInfo) auf, um den Decimal -Wert für die aktuelle Kultur zu formatieren.
Double Ruft Double.ToString("G", NumberFormatInfo.CurrentInfo) auf, um den Double -Wert für die aktuelle Kultur zu formatieren.
Int16 Ruft Int16.ToString("G", NumberFormatInfo.CurrentInfo) auf, um den Int16 -Wert für die aktuelle Kultur zu formatieren.
Int32 Ruft Int32.ToString("G", NumberFormatInfo.CurrentInfo) auf, um den Int32 -Wert für die aktuelle Kultur zu formatieren.
Int64 Ruft Int64.ToString("G", NumberFormatInfo.CurrentInfo) auf, um den Int64 -Wert für die aktuelle Kultur zu formatieren.
SByte Ruft SByte.ToString("G", NumberFormatInfo.CurrentInfo) auf, um den SByte -Wert für die aktuelle Kultur zu formatieren.
Single Ruft Single.ToString("G", NumberFormatInfo.CurrentInfo) auf, um den Single -Wert für die aktuelle Kultur zu formatieren.
UInt16 Ruft UInt16.ToString("G", NumberFormatInfo.CurrentInfo) auf, um den UInt16 -Wert für die aktuelle Kultur zu formatieren.
UInt32 Ruft UInt32.ToString("G", NumberFormatInfo.CurrentInfo) auf, um den UInt32 -Wert für die aktuelle Kultur zu formatieren.
UInt64 Ruft UInt64.ToString("G", NumberFormatInfo.CurrentInfo) auf, um den UInt64 -Wert für die aktuelle Kultur zu formatieren.

ToString-Methode und Formatzeichenfolgen

Wenn ein Objekt über eine einzelne Zeichenfolgendarstellung verfügt, ist das Verwenden der ToString -Standardmethode oder das Überschreiben von ToString angemessen. Der Wert eines Objekts weist jedoch häufig mehrere Darstellungen auf. Beispielsweise kann die Temperatur in Grad Fahrenheit, Grad Celsius oder Kelvin ausgedrückt werden. Entsprechend kann der ganzzahlige Wert 10 unterschiedlich dargestellt werden, z. B. als 10, 10.0, 1.0e01 oder $10.00.

Damit ein einzelner Wert mehrere Zeichenfolgendarstellungen aufweisen kann, verwendet .NET Formatzeichenfolgen. Eine Formatzeichenfolge ist eine Zeichenfolge, die einen oder mehrere vordefinierte Formatbezeichner enthält. Dies sind einzelne Zeichen oder Gruppen von Zeichen, die definieren, wie die ToString -Methode die Ausgabe formatieren soll. Die Formatzeichenfolge wird dann als Parameter an die ToString -Methode des Objekts übergeben und bestimmt, wie die Zeichenfolgendarstellung des Werts dieses Objekts angezeigt werden soll.

Alle numerischen Typen sowie die Datums- und Uhrzeittypen und die Enumerationstypen in .NET unterstützen einen vordefinierten Satz von Formatbezeichnern. Sie können auch Formatzeichenfolgen verwenden, um mehrere Zeichenfolgendarstellungen der anwendungsdefinierten Datentypen zu definieren.

Standardformatzeichenfolgen

Standardformatzeichenfolgen enthalten einen einzelnen Formatbezeichner. Dabei handelt es sich um ein alphabetisches Zeichen, das die Zeichenfolgendarstellung des Objekts definiert, auf das es angewendet wird. Außerden enthalten sie einen optionalen Genauigkeitsbezeichner, der angibt, wie viele Stellen in der Ergebniszeichenfolge angezeigt werden. Wenn der Genauigkeitsbezeichner nicht angegeben oder nicht unterstützt wird, entspricht ein Standardformatbezeichner einer Standardformatzeichenfolge.

.NET definiert einen Satz von Standardformatbezeichnern für alle numerischen Typen, alle Datums- und Uhrzeittypen und alle Enumerationstypen. Beispielsweise definieren die einzelnen Kategorien den Standardformatbezeichner "G", der eine allgemeine Zeichenfolgendarstellung für einen Wert dieses Typs definiert.

Standardformatzeichenfolgen für Enumerationstypen steuern die Zeichenfolgendarstellung eines Werts direkt. Die an die ToString-Methode eines Enumerationswerts übergebenen Formatzeichenfolgen bestimmen, ob der Wert mit seinem Zeichenfolgennamen (Formatbezeichner „G“ und „F“), seinem zugrunde liegenden ganzzahligen Wert (Formatbezeichner „D“) oder seinem Hexadezimalwert (Formatbezeichner „X“) angezeigt wird. Im folgenden Beispiel wird die Verwendung von Standardformatzeichenfolgen zum Formatieren eines DayOfWeek -Enumerationswerts veranschaulicht.

DayOfWeek thisDay = DayOfWeek.Monday;
string[] formatStrings = {"G", "F", "D", "X"};

foreach (string formatString in formatStrings)
   Console.WriteLine(thisDay.ToString(formatString));
// The example displays the following output:
//       Monday
//       Monday
//       1
//       00000001
Dim thisDay As DayOfWeek = DayOfWeek.Monday
Dim formatStrings() As String = {"G", "F", "D", "X"}

For Each formatString As String In formatStrings
    Console.WriteLine(thisDay.ToString(formatString))
Next
' The example displays the following output:
'       Monday
'       Monday
'       1
'       00000001

Weitere Informationen über Enumerationsformatzeichenfolgen finden Sie unter Enumeration Format Strings.

Standardformatzeichenfolgen für numerische Typen definieren normalerweise eine Ergebniszeichenfolge, deren genaue Darstellung von einem oder mehreren Eigenschaftswerten gesteuert wird. Beispielsweise formatiert der Formatbezeichner "C" eine Zahl als Währungswert. Wenn Sie die ToString-Methode mit dem Formatbezeichner „C“ als einzigem Parameter aufrufen, werden die folgenden Eigenschaftswerte des NumberFormatInfo-Objekts der aktuellen Kultur verwendet, um die Zeichenfolgendarstellung des numerischen Werts zu definieren:

  • Die CurrencySymbol-Eigenschaft, die das Währungssymbol der aktuellen Kultur angibt.

  • Die CurrencyNegativePattern -Eigenschaft oder die CurrencyPositivePattern -Eigenschaft, die eine ganz Zahl zurückgeben, die Folgendes bestimmt:

    • Die Platzierung des Währungssymbols.

    • Ob negative Werte durch ein führendes negatives Vorzeichen, ein nachfolgendes negatives Vorzeichen oder durch Klammern angegeben werden.

    • Ob zwischen dem numerischen Wert und dem Währungssymbol ein Leerzeichen angezeigt wird.

  • Die CurrencyDecimalDigits -Eigenschaft, die die Anzahl der Dezimalstellen in der Ergebniszeichenfolge definiert.

  • Die CurrencyDecimalSeparator -Eigenschaft, die das Dezimaltrennzeichen in der Ergebniszeichenfolge definiert.

  • Die CurrencyGroupSeparator -Eigenschaft, die das Gruppentrennzeichen definiert.

  • Die CurrencyGroupSizes -Eigenschaft, die die Anzahl der Stellen in jeder Gruppe links vom Dezimaltrennzeichen definiert.

  • Die NegativeSign -Eigenschaft, die das negative Vorzeichen bestimmt, das in der Ergebniszeichenfolge verwendet wird, wenn negative Werte nicht mit Klammern angegeben werden.

Darüber hinaus enthalten numerische Formatzeichenfolgen möglicherweise einen Genauigkeitsbezeichner. Die Bedeutung dieses Bezeichners ist abhängig von der Formatzeichenfolge, mit der er verwendet wird. In aller Regel wird dadurch jedoch entweder die Gesamtzahl der Stellen oder die Anzahl der Dezimalstellen angegeben, die in der Ergebniszeichenfolge erscheinen soll. So werden im folgenden Beispiel die numerische Standardzeichenfolge "X4" sowie ein Genauigkeitsbezeichner angegeben, um einen Zeichenfolgenwert mit vier Hexadezimalzahlen zu erstellen.

byte[] byteValues = { 12, 163, 255 };
foreach (byte byteValue in byteValues)
   Console.WriteLine(byteValue.ToString("X4"));
// The example displays the following output:
//       000C
//       00A3
//       00FF
Dim byteValues() As Byte = {12, 163, 255}
For Each byteValue As Byte In byteValues
    Console.WriteLine(byteValue.ToString("X4"))
Next
' The example displays the following output:
'       000C
'       00A3
'       00FF

Weitere Informationen zu standardmäßigen numerischen Formatierungszeichenfolgen finden Sie unter Standard Numeric Format Strings.

Standardformatzeichenfolgen für Datums- und Uhrzeitwerte sind Aliase für benutzerdefinierte Formatzeichenfolgen, die von einer bestimmten DateTimeFormatInfo -Eigenschaft gespeichert werden. Beispielsweise werden durch Aufrufen der ToString-Methode eines Datums- und Uhrzeitwerts mit dem Formatbezeichner „D“ das Datum und die Uhrzeit mit der benutzerdefinierten Formatzeichenfolge angezeigt, die in der DateTimeFormatInfo.LongDatePattern-Eigenschaft der aktuellen Kultur gespeichert sind. (Weitere Informationen zu benutzerdefinierten Formatzeichenfolgen finden Sie im nächsten Abschnitt.) Diese Beziehung wird anhand des folgenden Beispiels veranschaulicht.

using System;
using System.Globalization;

public class Example
{
   public static void Main()
   {
      DateTime date1 = new DateTime(2009, 6, 30);
      Console.WriteLine("D Format Specifier:     {0:D}", date1);
      string longPattern = CultureInfo.CurrentCulture.DateTimeFormat.LongDatePattern;
      Console.WriteLine("'{0}' custom format string:     {1}",
                        longPattern, date1.ToString(longPattern));
   }
}
// The example displays the following output when run on a system whose
// current culture is en-US:
//    D Format Specifier:     Tuesday, June 30, 2009
//    'dddd, MMMM dd, yyyy' custom format string:     Tuesday, June 30, 2009
Imports System.Globalization

Module Example
    Public Sub Main0()
        Dim date1 As Date = #6/30/2009#
        Console.WriteLine("D Format Specifier:     {0:D}", date1)
        Dim longPattern As String = CultureInfo.CurrentCulture.DateTimeFormat.LongDatePattern
        Console.WriteLine("'{0}' custom format string:     {1}",
                          longPattern, date1.ToString(longPattern))
    End Sub
End Module
' The example displays the following output when run on a system whose
' current culture is en-US:
'    D Format Specifier:     Tuesday, June 30, 2009
'    'dddd, MMMM dd, yyyy' custom format string:     Tuesday, June 30, 2009

Weitere Informationen über Standardformatzeichenfolgen für Datum und Uhrzeit finden Sie unter Standard Date and Time Format Strings.

Sie können Standardformatzeichenfolgen auch verwenden, um die Zeichenfolgendarstellung eines anwendungsdefinierten Objekts anzugeben, die von der ToString(String)-Methode des Objekts erstellt wird. Sie können die spezifischen Standardformatbezeichner definieren, die von dem Objekt unterstützt werden, und Sie können angeben, ob die Groß- und Kleinschreibung beachtet werden soll. Ihre Implementierung der ToString(String)-Methode sollte Folgendes unterstützen:

  • Den Formatbezeichner "G", der ein übliches oder allgemeines Format des Objekts darstellt. Die parameterlose Überladung der ToString -Methode des Objekts sollte die zugehörige ToString(String) -Überladung aufrufen und die Standardformatzeichenfolge "G" übergeben.

  • Unterstützung für einen Formatbezeichner, der gleich einem NULL-Verweis (Nothing in Visual Basic) ist. Ein Formatbezeichner, der gleich einem NULL-Verweis ist, sollte als äquivalent mit dem "G"-Formatbezeichner angesehen werden.

Beispielsweise kann eine Temperature-Klasse die Temperatur in Grad Celsius intern speichern und Formatbezeichner verwenden, um den Wert des Temperature-Objekts in Grad Celsius, Grad Fahrenheit und Kelvin darzustellen. Dies wird im folgenden Beispiel veranschaulicht.

using System;

public class Temperature
{
   private decimal m_Temp;

   public Temperature(decimal temperature)
   {
      this.m_Temp = temperature;
   }

   public decimal Celsius
   {
      get { return this.m_Temp; }
   }

   public decimal Kelvin
   {
      get { return this.m_Temp + 273.15m; }
   }

   public decimal Fahrenheit
   {
      get { return Math.Round(((decimal) (this.m_Temp * 9 / 5 + 32)), 2); }
   }

   public override string ToString()
   {
      return this.ToString("C");
   }

   public string ToString(string format)
   {
      // Handle null or empty string.
      if (String.IsNullOrEmpty(format)) format = "C";
      // Remove spaces and convert to uppercase.
      format = format.Trim().ToUpperInvariant();

      // Convert temperature to Fahrenheit and return string.
      switch (format)
      {
         // Convert temperature to Fahrenheit and return string.
         case "F":
            return this.Fahrenheit.ToString("N2") + " °F";
         // Convert temperature to Kelvin and return string.
         case "K":
            return this.Kelvin.ToString("N2") + " K";
         // return temperature in Celsius.
         case "G":
         case "C":
            return this.Celsius.ToString("N2") + " °C";
         default:
            throw new FormatException(String.Format("The '{0}' format string is not supported.", format));
      }
   }
}

public class Example1
{
   public static void Main()
   {
      Temperature temp1 = new Temperature(0m);
      Console.WriteLine(temp1.ToString());
      Console.WriteLine(temp1.ToString("G"));
      Console.WriteLine(temp1.ToString("C"));
      Console.WriteLine(temp1.ToString("F"));
      Console.WriteLine(temp1.ToString("K"));

      Temperature temp2 = new Temperature(-40m);
      Console.WriteLine(temp2.ToString());
      Console.WriteLine(temp2.ToString("G"));
      Console.WriteLine(temp2.ToString("C"));
      Console.WriteLine(temp2.ToString("F"));
      Console.WriteLine(temp2.ToString("K"));

      Temperature temp3 = new Temperature(16m);
      Console.WriteLine(temp3.ToString());
      Console.WriteLine(temp3.ToString("G"));
      Console.WriteLine(temp3.ToString("C"));
      Console.WriteLine(temp3.ToString("F"));
      Console.WriteLine(temp3.ToString("K"));

      Console.WriteLine(String.Format("The temperature is now {0:F}.", temp3));
   }
}
// The example displays the following output:
//       0.00 °C
//       0.00 °C
//       0.00 °C
//       32.00 °F
//       273.15 K
//       -40.00 °C
//       -40.00 °C
//       -40.00 °C
//       -40.00 °F
//       233.15 K
//       16.00 °C
//       16.00 °C
//       16.00 °C
//       60.80 °F
//       289.15 K
//       The temperature is now 16.00 °C.
Public Class Temperature
    Private m_Temp As Decimal

    Public Sub New(temperature As Decimal)
        Me.m_Temp = temperature
    End Sub

    Public ReadOnly Property Celsius() As Decimal
        Get
            Return Me.m_Temp
        End Get
    End Property

    Public ReadOnly Property Kelvin() As Decimal
        Get
            Return Me.m_Temp + 273.15D
        End Get
    End Property

    Public ReadOnly Property Fahrenheit() As Decimal
        Get
            Return Math.Round(CDec(Me.m_Temp * 9 / 5 + 32), 2)
        End Get
    End Property

    Public Overrides Function ToString() As String
        Return Me.ToString("C")
    End Function

    Public Overloads Function ToString(format As String) As String
        ' Handle null or empty string.
        If String.IsNullOrEmpty(format) Then format = "C"
        ' Remove spaces and convert to uppercase.
        format = format.Trim().ToUpperInvariant()

        Select Case format
            Case "F"
                ' Convert temperature to Fahrenheit and return string.
                Return Me.Fahrenheit.ToString("N2") & " °F"
            Case "K"
                ' Convert temperature to Kelvin and return string.
                Return Me.Kelvin.ToString("N2") & " K"
            Case "C", "G"
                ' Return temperature in Celsius.
                Return Me.Celsius.ToString("N2") & " °C"
            Case Else
                Throw New FormatException(String.Format("The '{0}' format string is not supported.", format))
        End Select
    End Function
End Class

Public Module Example1
    Public Sub Main1()
        Dim temp1 As New Temperature(0D)
        Console.WriteLine(temp1.ToString())
        Console.WriteLine(temp1.ToString("G"))
        Console.WriteLine(temp1.ToString("C"))
        Console.WriteLine(temp1.ToString("F"))
        Console.WriteLine(temp1.ToString("K"))

        Dim temp2 As New Temperature(-40D)
        Console.WriteLine(temp2.ToString())
        Console.WriteLine(temp2.ToString("G"))
        Console.WriteLine(temp2.ToString("C"))
        Console.WriteLine(temp2.ToString("F"))
        Console.WriteLine(temp2.ToString("K"))

        Dim temp3 As New Temperature(16D)
        Console.WriteLine(temp3.ToString())
        Console.WriteLine(temp3.ToString("G"))
        Console.WriteLine(temp3.ToString("C"))
        Console.WriteLine(temp3.ToString("F"))
        Console.WriteLine(temp3.ToString("K"))

        Console.WriteLine(String.Format("The temperature is now {0:F}.", temp3))
    End Sub
End Module
' The example displays the following output:
'       0.00 °C
'       0.00 °C
'       0.00 °C
'       32.00 °F
'       273.15 K
'       -40.00 °C
'       -40.00 °C
'       -40.00 °C
'       -40.00 °F
'       233.15 K
'       16.00 °C
'       16.00 °C
'       16.00 °C
'       60.80 °F
'       289.15 K
'       The temperature is now 16.00 °C.

Benutzerdefinierte Formatzeichenfolgen

Zusätzlich zu den Standardformatzeichenfolgen definiert .NET benutzerdefinierte Formatzeichenfolgen für numerische Werte und Datums- und Uhrzeitwerte. Eine benutzerdefinierte Formatzeichenfolge besteht aus einem oder mehreren benutzerdefinierten Formatbezeichnern, die die Zeichenfolgendarstellung eines Werts definieren. Beispielsweise konvertiert die benutzerdefinierte Datums- und Uhrzeitformatzeichenfolge "yyyy/mm/dd hh:mm:ss.ffff t zzz" ein Datum für die Kultur en-US wie folgt in die entsprechende Zeichenfolgendarstellung: "2008/11/15 07:45:00.0000 P -08:00". Analog konvertiert die benutzerdefinierte Formatzeichenfolge "0000" den ganzzahligen Wert 12 in "0012". Eine vollständige Liste von benutzerdefinierten Formatzeichenfolgen finden Sie unter Custom Date and Time Format Strings und Custom Numeric Format Strings.

Wenn eine Formatzeichenfolge aus einem einzelnen benutzerdefinierten Formatbezeichner besteht, sollte dem Formatbezeichner das Prozentsymbol (%) vorangestellt werden, um Verwechslungen mit einem Standardformatbezeichner zu vermeiden. Im folgenden Beispiel wird der benutzerdefinierte Formatbezeichner "M" verwendet, um eine einstellige oder zweistellige Ziffer für einen bestimmten Tag des Monats anzuzeigen.

DateTime date1 = new DateTime(2009, 9, 8);
Console.WriteLine(date1.ToString("%M"));       // Displays 9
Dim date1 As Date = #09/08/2009#
Console.WriteLine(date1.ToString("%M"))      ' Displays 9

Viele Standardformatzeichenfolgen für Datums- und Uhrzeitwerte sind Aliase für benutzerdefinierte Formatzeichenfolgen, die von Eigenschaften des DateTimeFormatInfo -Objekts definiert werden. Benutzerdefinierte Formatzeichenfolgen ermöglichen außerdem eine hohe Flexibilität beim Bereitstellen von anwendungsdefinierter Formatierung für numerische Werte oder Datums- und Uhrzeitwerte. Sie können eigene benutzerdefinierte Ergebniszeichenfolgen für numerische Werte und für Datums- und Uhrzeitwerte definieren, indem Sie mehrere benutzerdefinierte Formatbezeichner zu einer einzelnen benutzerdefinierten Formatzeichenfolge kombinieren. Im folgenden Beispiel wird eine benutzerdefinierte Formatzeichenfolge definiert, die im Anschluss an den Namen des Monats, den Tag und das Jahr den Tag der Woche in Klammern anzeigt.

string customFormat = "MMMM dd, yyyy (dddd)";
DateTime date1 = new DateTime(2009, 8, 28);
Console.WriteLine(date1.ToString(customFormat));
// The example displays the following output if run on a system
// whose language is English:
//       August 28, 2009 (Friday)
Dim customFormat As String = "MMMM dd, yyyy (dddd)"
Dim date1 As Date = #8/28/2009#
Console.WriteLine(date1.ToString(customFormat))
' The example displays the following output if run on a system
' whose language is English:
'       August 28, 2009 (Friday)      

Das folgende Beispiel definiert eine benutzerdefinierte Formatzeichenfolge, die einen Int64 -Wert als standardmäßige, siebenstellige US-Telefonnummer mit der Ortskennzahl anzeigt.

using System;

public class Example17
{
   public static void Main()
   {
      long number = 8009999999;
      string fmt = "000-000-0000";
      Console.WriteLine(number.ToString(fmt));
   }
}
// The example displays the following output:
//        800-999-9999
Module Example18
    Public Sub Main18()
        Dim number As Long = 8009999999
        Dim fmt As String = "000-000-0000"
        Console.WriteLine(number.ToString(fmt))
    End Sub
End Module
' The example displays the following output:

' The example displays the following output:
'       800-999-9999

Standardformatzeichenfolgen decken i. d. R. die meisten der Formatierungsanforderungen für anwendungsdefinierte Typen ab. Sie können jedoch auch benutzerdefinierte Formatbezeichner definieren, um Typen zu formatieren.

Formatzeichenfolgen und .NET-Typen

Alle numerischen Typen (d.h. Byte, Decimal, Double, Int16, Int32, Int64, SByte, Single, UInt16, UInt32, UInt64 und BigInteger) sowie DateTime, DateTimeOffset, TimeSpan, Guid und alle Enumerationstypen unterstützen die Formatierung mit Formatzeichenfolgen. Informationen zu bestimmten Formatzeichenfolgen, die von jedem Typ unterstützt werden, finden Sie in den folgenden Themen:

Titel Definition
Standard Numeric Format Strings Beschreibt als Standard verwendete Formatzeichenfolgen, mit denen häufig verwendete Zeichenfolgenentsprechungen von numerischen Werten erstellt werden.
Custom Numeric Format Strings Beschreibt benutzerdefinierte Formatzeichenfolgen, die anwendungsspezifische Formate für numerische Werte erstellen.
Standard-Formatzeichenfolgen für Datum und Uhrzeit Beschreibt als Standard verwendete Formatzeichenfolgen, mit denen häufig verwendete Zeichenfolgenentsprechungen von DateTime- undDateTimeOffset-Werten erstellt werden.
Benutzerdefinierte Formatzeichenfolgen für Datum und Uhrzeit Beschreibt benutzerdefinierte Formatzeichenfolgen, die anwendungsspezifische Formate für DateTime- und DateTimeOffset-Werte erstellen.
TimeSpan-Standardformatzeichenfolgen Beschreibt als Standard verwendete Formatzeichenfolgen, mit denen häufig verwendete Zeichenfolgenentsprechungen von Zeitintervallen erstellt werden.
Benutzerdefinierte TimeSpan-Formatzeichenfolgen Beschreibt benutzerdefinierte Formatzeichenfolgen, die anwendungsspezifische Formate für Zeitintervalle erstellen.
Enumeration Format Strings Beschreibt als Standard verwendete Formatzeichenfolgen, mit denen Zeichenfolgenentsprechungen von Enumerationswerten erstellt werden.
Guid.ToString(String) Beschreibt die Standard-Formatzeichenfolgen für Guid -Werte.

Kulturabhängige Formatierung mit Formatanbietern

Obwohl Sie mit Formatbezeichnern die Formatierung von Objekten anpassen können, sind für eine sinnvolle Zeichenfolgendarstellung von Objekten oft zusätzliche Formatierungsinformationen erforderlich. Beispielsweise ist für das Formatieren einer Zahl als Währungswert mit der Standardformatzeichenfolge "C" oder mit einer benutzerdefinierten Formatzeichenfolge wie "$ #,#.00" mindestens erforderlich, dass Informationen über das richtige Währungssymbol, das richtige Gruppentrennzeichen und das richtige Dezimaltrennzeichen verfügbar sind, um in die formatierte Zeichenfolge eingeschlossen zu werden. In .NET werden diese zusätzlichen Formatierungsinformationen durch die IFormatProvider-Schnittstelle verfügbar gemacht. Diese wird als Parameter für eine oder mehrere Überladungen der ToString-Methode von numerischen Typen sowie von Datums- und Uhrzeittypen bereitgestellt. IFormatProvider-Implementierungen werden in .NET verwendet, um eine kulturabhängige Formatierung zu unterstützen. Im folgenden Beispiel wird veranschaulicht, wie sich die Zeichenfolgendarstellung eines Objekts ändert, wenn die Formatierung mit drei IFormatProvider -Objekten erfolgt, die verschiedene Kulturen darstellen.

using System;
using System.Globalization;

public class Example18
{
   public static void Main()
   {
      decimal value = 1603.42m;
      Console.WriteLine(value.ToString("C3", new CultureInfo("en-US")));
      Console.WriteLine(value.ToString("C3", new CultureInfo("fr-FR")));
      Console.WriteLine(value.ToString("C3", new CultureInfo("de-DE")));
   }
}
// The example displays the following output:
//       $1,603.420
//       1 603,420 €
//       1.603,420 €
Imports System.Globalization

Public Module Example11
    Public Sub Main11()
        Dim value As Decimal = 1603.42D
        Console.WriteLine(value.ToString("C3", New CultureInfo("en-US")))
        Console.WriteLine(value.ToString("C3", New CultureInfo("fr-FR")))
        Console.WriteLine(value.ToString("C3", New CultureInfo("de-DE")))
    End Sub
End Module
' The example displays the following output:
'       $1,603.420
'       1 603,420 €
'       1.603,420 €

Die IFormatProvider -Schnittstelle enthält die GetFormat(Type)-Methode. Diese weist einen einzelnen Parameter auf, der den Typ des Objekts angibt, das Formatierungsinformationen bereitstellt. Wenn die Methode ein Objekt dieses Typs bereitstellen kann, wird dieses zurückgegeben. Andernfalls wird ein NULL-Verweis (Nothing in Visual Basic) zurückgegeben.

IFormatProvider.GetFormat ist eine Rückrufmethode. Wenn Sie eine ToString -Methodenüberladung aufrufen, die einen IFormatProvider -Parameter einschließt, wird die GetFormat -Methode dieses IFormatProvider -Objekts aufgerufen. Die GetFormat -Methode ist dafür verantwortlich, ein Objekt zurückzugeben, das die notwendigen Formatierungsinformationen, wie vom formatType -Parameter angegeben, für die ToString -Methode bereitstellt.

Eine Reihe von Formatierungs- oder Zeichenfolgenkonvertierungsmethoden enthalten einen Parameter vom Typ IFormatProvider; in vielen Fällen wird der Wert des Parameters beim Aufrufen der Methode jedoch ignoriert. In der folgenden Tabelle sind einige Formatierungsmethoden aufgeführt, die den Parameter und den Typ des Type -Objekts verwenden, die an die IFormatProvider.GetFormat -Methode übergeben werden.

Methode formatType -Parametertyp
ToString -Methode für numerische Typen System.Globalization.NumberFormatInfo
ToString-Methode für Datums- und Uhrzeittypen System.Globalization.DateTimeFormatInfo
String.Format System.ICustomFormatter
StringBuilder.AppendFormat System.ICustomFormatter

Hinweis

Die ToString -Methoden der numerischen Typen und der Datums- und Uhrzeittypen werden überladen, und nur einige der Überladungen enthalten einen IFormatProvider -Parameter. Wenn eine Methode keinen Parameter vom Typ IFormatProvideraufweist, wird stattdessen das Objekt übergeben, das von der CultureInfo.CurrentCulture -Eigenschaft zurückgegeben wird. Beispielsweise führt ein Aufruf der Int32.ToString() -Standardmethode letztendlich zu einem Methodenaufruf wie dem folgenden: Int32.ToString("G", System.Globalization.CultureInfo.CurrentCulture).

.NET stellt drei Klassen bereit, die IFormatProvider implementieren:

Sie können auch einen eigenen Formatanbieter implementieren, um eine dieser Klassen zu ersetzen. Die GetFormat-Methode Ihrer Implementierung muss jedoch ein Objekt eines in der vorangehenden Tabelle aufgeführten Typs zurückgeben, um Formatierungsinformationen für die ToString-Methode bereitzustellen.

Kulturabhängige Formatierung von numerischen Werten

Standardmäßig ist die Formatierung von numerischen Werten kulturabhängig. Wenn Sie beim Aufrufen einer Formatierungsmethode keine Kultur angeben, werden die Formatierungskonventionen der aktuellen Threadkultur verwendet. Dies wird im folgenden Beispiel veranschaulicht, das die aktuelle Threadkultur viermal ändert und anschließend die Decimal.ToString(String) -Methode aufruft. In allen Fällen gibt die Ergebniszeichenfolge die Formatierungskonventionen der aktuellen Kultur wieder. Dies liegt daran, dass die ToString - und ToString(String) -Methoden die Aufrufe der ToString(String, IFormatProvider) -Methode jedes numerischen Typs umschließen.

using System.Globalization;

public class Example6
{
   public static void Main()
   {
      string[] cultureNames = { "en-US", "fr-FR", "es-MX", "de-DE" };
      Decimal value = 1043.17m;

      foreach (var cultureName in cultureNames) {
         // Change the current culture.
         CultureInfo.CurrentCulture = CultureInfo.CreateSpecificCulture(cultureName);
         Console.WriteLine($"The current culture is {CultureInfo.CurrentCulture.Name}");
         Console.WriteLine(value.ToString("C2"));
         Console.WriteLine();
      }
   }
}
// The example displays the following output:
//       The current culture is en-US
//       $1,043.17
//
//       The current culture is fr-FR
//       1 043,17 €
//
//       The current culture is es-MX
//       $1,043.17
//
//       The current culture is de-DE
//       1.043,17 €
Imports System.Globalization

Module Example6
    Public Sub Main6()
        Dim cultureNames() As String = {"en-US", "fr-FR", "es-MX", "de-DE"}
        Dim value As Decimal = 1043.17D

        For Each cultureName In cultureNames
            ' Change the current culture.
            CultureInfo.CurrentCulture = CultureInfo.CreateSpecificCulture(cultureName)
            Console.WriteLine($"The current culture is {CultureInfo.CurrentCulture.Name}")
            Console.WriteLine(value.ToString("C2"))
            Console.WriteLine()
        Next
    End Sub
End Module
' The example displays the following output:
'       The current culture is en-US
'       $1,043.17
'       
'       The current culture is fr-FR
'       1 043,17 €
'       
'       The current culture is es-MX
'       $1,043.17
'       
'       The current culture is de-DE
'       1.043,17 €

Sie können einen numerischen Wert für eine bestimmte Kultur ebenso formatieren, indem Sie eine ToString -Überladung aufrufen, die einen provider -Parameter hat, und ihr eines der folgenden Objekte übergeben:

  • Ein CultureInfo -Objekt, das die Kultur darstellt, deren Formatierungskonventionen verwendet werden sollen. Die zugehörige CultureInfo.GetFormat -Methode gibt den Wert der CultureInfo.NumberFormat -Eigenschaft zurück, die das NumberFormatInfo -Objekt ist, das kulturspezifische Formatierungsinformationen für numerische Werte bereitstellt.

  • Ein NumberFormatInfo -Objekt, das die kulturspezifischen Formatierungskonventionen definiert, die verwendet werden sollen. Die zugehörige GetFormat -Methode gibt eine Instanz von sich selbst zurück.

Im folgenden Beispiel werden NumberFormatInfo -Objekte verwendet, die die Kulturen Englisch (USA) und Englisch (Großbritannien) sowie die neutralen Kulturen Französisch und Russisch darstellen, um eine Gleitkommazahl zu formatieren.

using System.Globalization;

public class Example7
{
    public static void Main()
    {
        double value = 1043.62957;
        string[] cultureNames = { "en-US", "en-GB", "ru", "fr" };

        foreach (string? name in cultureNames)
        {
            NumberFormatInfo nfi = CultureInfo.CreateSpecificCulture(name).NumberFormat;
            Console.WriteLine("{0,-6} {1}", name + ":", value.ToString("N3", nfi));
        }
    }
}
// The example displays the following output:
//       en-US: 1,043.630
//       en-GB: 1,043.630
//       ru:    1 043,630
//       fr:    1 043,630
Imports System.Globalization

Module Example7
    Public Sub Main7()
        Dim value As Double = 1043.62957
        Dim cultureNames() As String = {"en-US", "en-GB", "ru", "fr"}

        For Each name In cultureNames
            Dim nfi As NumberFormatInfo = CultureInfo.CreateSpecificCulture(name).NumberFormat
            Console.WriteLine("{0,-6} {1}", name + ":", value.ToString("N3", nfi))
        Next
    End Sub
End Module
' The example displays the following output:
'       en-US: 1,043.630
'       en-GB: 1,043.630
'       ru:    1 043,630
'       fr:    1 043,630

Kulturabhängige Formatierung von Datums- und Uhrzeitwerten

Standardmäßig ist die Formatierung von Daten- und Uhrzeitwerten kulturabhängig. Wenn Sie beim Aufrufen einer Formatierungsmethode keine Kultur angeben, werden die Formatierungskonventionen der aktuellen Threadkultur verwendet. Dies wird im folgenden Beispiel veranschaulicht, das die aktuelle Threadkultur viermal ändert und anschließend die DateTime.ToString(String) -Methode aufruft. In allen Fällen gibt die Ergebniszeichenfolge die Formatierungskonventionen der aktuellen Kultur wieder. Dies liegt daran, dass die DateTime.ToString()-, DateTime.ToString(String)-, DateTimeOffset.ToString()- und DateTimeOffset.ToString(String) -Methoden die Aufrufe der DateTime.ToString(String, IFormatProvider) - und DateTimeOffset.ToString(String, IFormatProvider) -Methoden umschließen.

using System.Globalization;

public class Example4
{
   public static void Main()
   {
      string[] cultureNames = { "en-US", "fr-FR", "es-MX", "de-DE" };
      DateTime dateToFormat = new DateTime(2012, 5, 28, 11, 30, 0);

      foreach (var cultureName in cultureNames) {
         // Change the current culture.
         CultureInfo.CurrentCulture = CultureInfo.CreateSpecificCulture(cultureName);
         Console.WriteLine($"The current culture is {CultureInfo.CurrentCulture.Name}");
         Console.WriteLine(dateToFormat.ToString("F"));
         Console.WriteLine();
      }
   }
}
// The example displays the following output:
//       The current culture is en-US
//       Monday, May 28, 2012 11:30:00 AM
//
//       The current culture is fr-FR
//       lundi 28 mai 2012 11:30:00
//
//       The current culture is es-MX
//       lunes, 28 de mayo de 2012 11:30:00 a.m.
//
//       The current culture is de-DE
//       Montag, 28. Mai 2012 11:30:00
Imports System.Globalization
Imports System.Threading

Module Example4
    Public Sub Main4()
        Dim cultureNames() As String = {"en-US", "fr-FR", "es-MX", "de-DE"}
        Dim dateToFormat As Date = #5/28/2012 11:30AM#

        For Each cultureName In cultureNames
            ' Change the current culture.
            CultureInfo.CurrentCulture = CultureInfo.CreateSpecificCulture(cultureName)
            Console.WriteLine($"The current culture is {CultureInfo.CurrentCulture.Name}")
            Console.WriteLine(dateToFormat.ToString("F"))
            Console.WriteLine()
        Next
    End Sub
End Module
' The example displays the following output:
'       The current culture is en-US
'       Monday, May 28, 2012 11:30:00 AM
'       
'       The current culture is fr-FR
'       lundi 28 mai 2012 11:30:00
'       
'       The current culture is es-MX
'       lunes, 28 de mayo de 2012 11:30:00 a.m.
'       
'       The current culture is de-DE
'       Montag, 28. Mai 2012 11:30:00 

Sie können einen Datums- und Uhrzeitwert für eine bestimmte Kultur ebenso formatieren, indem Sie eine DateTime.ToString - oder DateTimeOffset.ToString -Überladung aufrufen, die einen provider -Parameter hat, und ihr eines der folgenden Objekte übergeben:

  • Ein CultureInfo -Objekt, das die Kultur darstellt, deren Formatierungskonventionen verwendet werden sollen. Die zugehörige CultureInfo.GetFormat -Methode gibt den Wert der CultureInfo.DateTimeFormat -Eigenschaft zurück, die das DateTimeFormatInfo -Objekt ist, das kulturspezifische Formatierungsinformationen für Datums- und Uhrzeitwerte bereitstellt.

  • Ein DateTimeFormatInfo -Objekt, das die kulturspezifischen Formatierungskonventionen definiert, die verwendet werden sollen. Die zugehörige GetFormat -Methode gibt eine Instanz von sich selbst zurück.

Im folgenden Beispiel werden DateTimeFormatInfo -Objekte verwendet, die die Kulturen Englisch (USA) und Englisch (Großbritannien) sowie die neutralen Kulturen Französisch und Russisch darstellen, um ein Datum zu formatieren.

using System.Globalization;

public class Example5
{
   public static void Main()
   {
      DateTime dat1 = new(2012, 5, 28, 11, 30, 0);
      string[] cultureNames = { "en-US", "en-GB", "ru", "fr" };

      foreach (var name in cultureNames) {
         DateTimeFormatInfo dtfi = CultureInfo.CreateSpecificCulture(name).DateTimeFormat;
         Console.WriteLine($"{name}: {dat1.ToString(dtfi)}");
      }
   }
}
// The example displays the following output:
//       en-US: 5/28/2012 11:30:00 AM
//       en-GB: 28/05/2012 11:30:00
//       ru: 28.05.2012 11:30:00
//       fr: 28/05/2012 11:30:00
Imports System.Globalization

Module Example5
    Public Sub Main5()
        Dim dat1 As Date = #5/28/2012 11:30AM#
        Dim cultureNames() As String = {"en-US", "en-GB", "ru", "fr"}

        For Each name In cultureNames
            Dim dtfi As DateTimeFormatInfo = CultureInfo.CreateSpecificCulture(name).DateTimeFormat
            Console.WriteLine($"{name}: {dat1.ToString(dtfi)}")
        Next
    End Sub
End Module
' The example displays the following output:
'       en-US: 5/28/2012 11:30:00 AM
'       en-GB: 28/05/2012 11:30:00
'       ru: 28.05.2012 11:30:00
'       fr: 28/05/2012 11:30:00

IFormattable-Schnittstelle

Typen, die die ToString -Methode mit einer Formatzeichenfolge und einem IFormatProvider -Parameter überladen, implementieren i. d. R. auch die IFormattable -Schnittstelle. Diese Schnittstelle verfügt über einen einzelnen Member, IFormattable.ToString(String, IFormatProvider), der sowohl eine Formatzeichenfolge als auch einen Formatanbieter als Parameter einschließt.

Das Implementieren der IFormattable -Schnittstelle für die anwendungsdefinierte Klasse bietet zwei Vorteile:

Im folgenden Beispiel wird eine Temperature -Klasse definiert, die die IFormattable -Schnittstelle implementiert. Die Formatbezeichner "C" oder "G" werden darin unterstützt, um die Temperatur in Celsius anzuzeigen, der Formatbezeichner "F", um die Temperatur in Fahrenheit anzuzeigen, und der Formatbezeichner "KB", um die Temperatur in Kelvin anzuzeigen.

using System;
using System.Globalization;

namespace HotAndCold
{

    public class Temperature : IFormattable
    {
        private decimal m_Temp;

        public Temperature(decimal temperature)
        {
            this.m_Temp = temperature;
        }

        public decimal Celsius
        {
            get { return this.m_Temp; }
        }

        public decimal Kelvin
        {
            get { return this.m_Temp + 273.15m; }
        }

        public decimal Fahrenheit
        {
            get { return Math.Round((decimal)this.m_Temp * 9 / 5 + 32, 2); }
        }

        public override string ToString()
        {
            return this.ToString("G", null);
        }

        public string ToString(string format)
        {
            return this.ToString(format, null);
        }

        public string ToString(string format, IFormatProvider provider)
        {
            // Handle null or empty arguments.
            if (String.IsNullOrEmpty(format))
                format = "G";
            // Remove any white space and covert to uppercase.
            format = format.Trim().ToUpperInvariant();

            if (provider == null)
                provider = NumberFormatInfo.CurrentInfo;

            switch (format)
            {
                // Convert temperature to Fahrenheit and return string.
                case "F":
                    return this.Fahrenheit.ToString("N2", provider) + "°F";
                // Convert temperature to Kelvin and return string.
                case "K":
                    return this.Kelvin.ToString("N2", provider) + "K";
                // Return temperature in Celsius.
                case "C":
                case "G":
                    return this.Celsius.ToString("N2", provider) + "°C";
                default:
                    throw new FormatException(String.Format("The '{0}' format string is not supported.", format));
            }
        }
    }
Public Class Temperature : Implements IFormattable
    Private m_Temp As Decimal

    Public Sub New(temperature As Decimal)
        Me.m_Temp = temperature
    End Sub

    Public ReadOnly Property Celsius() As Decimal
        Get
            Return Me.m_Temp
        End Get
    End Property

    Public ReadOnly Property Kelvin() As Decimal
        Get
            Return Me.m_Temp + 273.15D
        End Get
    End Property

    Public ReadOnly Property Fahrenheit() As Decimal
        Get
            Return Math.Round(CDec(Me.m_Temp * 9 / 5 + 32), 2)
        End Get
    End Property

    Public Overrides Function ToString() As String
        Return Me.ToString("G", Nothing)
    End Function

    Public Overloads Function ToString(format As String) As String
        Return Me.ToString(format, Nothing)
    End Function

    Public Overloads Function ToString(format As String, provider As IFormatProvider) As String _
       Implements IFormattable.ToString

        ' Handle null or empty arguments.
        If String.IsNullOrEmpty(format) Then format = "G"
        ' Remove any white space and convert to uppercase.
        format = format.Trim().ToUpperInvariant()

        If provider Is Nothing Then provider = NumberFormatInfo.CurrentInfo

        Select Case format
     ' Convert temperature to Fahrenheit and return string.
            Case "F"
                Return Me.Fahrenheit.ToString("N2", provider) & "°F"
     ' Convert temperature to Kelvin and return string.
            Case "K"
                Return Me.Kelvin.ToString("N2", provider) & "K"
     ' Return temperature in Celsius.
            Case "C", "G"
                Return Me.Celsius.ToString("N2", provider) & "°C"
            Case Else
                Throw New FormatException(String.Format($"The '{format}' format string is not supported."))
        End Select
    End Function
End Class

Im folgenden Beispiel wird ein Temperature-Objekt instanziiert. Anschließend wird die ToString -Methode aufgerufen und mehrere zusammengesetzte Formatzeichenfolgen werden verwendet, um andere Zeichenfolgendarstellungen eines Temperature -Objekts zu erhalten. Die einzelnen Methoden rufen wiederum die IFormattable -Implementierung der Temperature -Klasse auf.

public class Example11
{
    public static void Main()
    {
        CultureInfo.CurrentCulture = CultureInfo.GetCultureInfo("en-US");
        Temperature temp = new Temperature(22m);
        Console.WriteLine(Convert.ToString(temp, new CultureInfo("ja-JP")));
        Console.WriteLine("Temperature: {0:K}", temp);
        Console.WriteLine("Temperature: {0:F}", temp);
        Console.WriteLine(String.Format(new CultureInfo("fr-FR"), "Temperature: {0:F}", temp));
    }
}
// The example displays the following output:
//       22.00°C
//       Temperature: 295.15K
//       Temperature: 71.60°F
//       Temperature: 71,60°F
Public Module Example12
    Public Sub Main12()
        Dim temp As New Temperature(22D)
        CultureInfo.CurrentCulture = CultureInfo.GetCultureInfo("en-US")
        Console.WriteLine(Convert.ToString(temp, New CultureInfo("ja-JP")))
        Console.WriteLine($"Temperature: {temp:K}")
        Console.WriteLine($"Temperature: {temp:F}")
        Console.WriteLine(String.Format(New CultureInfo("fr-FR"), $"Temperature: {temp:F}"))
    End Sub
End Module
' The example displays the following output:
'       22.00°C
'       Temperature: 295.15K
'       Temperature: 71.60°F
'       Temperature: 71,60°F

Kombinierte Formatierung

Einige Methoden wie String.Format und StringBuilder.AppendFormat unterstützen die kombinierte Formatierung. Eine kombinierte Formatzeichenfolge ist eine Vorlage, die verwendet wird, um eine einzelne Zeichenfolge zurückzugeben, die die Zeichenfolgendarstellung von 0 (null), einem oder mehreren Objekten beinhaltet. Jedes Objekt wird in der kombinierten Formatzeichenfolge durch ein indiziertes Formatelement dargestellt. Der Index des Formatelements entspricht der Position des Objekts, das es in der Parameterliste der Methode darstellt. Indizes sind nullbasiert. Beispielsweise wird im folgenden Aufruf der String.Format-Methode das erste Formatelement {0:D} durch die Zeichenfolgendarstellung von thatDate ersetzt. Das zweite Formatelement {1} wird durch die Zeichenfolgendarstellung item1 ersetzt, und das dritte Formatelement {2:C2} wird durch die Zeichenfolgendarstellung von item1.Value ersetzt.

result = String.Format("On {0:d}, the inventory of {1} was worth {2:C2}.",
                       thatDate, item1, item1.Value);
Console.WriteLine(result);
// The example displays output like the following if run on a system
// whose current culture is en-US:
//       On 5/1/2009, the inventory of WidgetA was worth $107.44.
result = String.Format("On {0:d}, the inventory of {1} was worth {2:C2}.",
                       thatDate, item1, item1.Value)
Console.WriteLine(result)
' The example displays output like the following if run on a system
' whose current culture is en-US:
'       On 5/1/2009, the inventory of WidgetA was worth $107.44.

Zusätzlich zum Ersetzen eines Formatelements durch die Zeichenfolgendarstellung seines entsprechenden Objekts können Sie mit Formatelementen auch Folgendes steuern:

  • Die spezifische Art, in der ein Objekt als Zeichenfolge dargestellt wird, wenn das Objekt die IFormattable -Schnittstelle implementiert und Formatzeichenfolgen unterstützt. Zu diesem Zweck geben Sie nach dem Index des Formatelements einen : (Doppelpunkt) ein, gefolgt von einer gültigen Formatzeichenfolge. Im vorherigen Beispiel wurde hierzu ein Datumswert mit der Formatzeichenfolge "d" (kurzes Datumsmuster) formatiert (z. B. {0:d}) und ein numerischer Wert mit der Formatzeichenfolge "C2" formatiert (z. B. {2:C2} ), um die Zahl als Währungswert mit zwei Dezimalstellen für Sekundenbruchteile darzustellen.

  • Die Breite des Felds, das die Zeichenfolgendarstellung des Objekts enthält, und die Ausrichtung der Zeichenfolgendarstellung in diesem Feld. Hierzu geben Sie nach dem Index des Formatelements ein , (Komma) ein, gefolgt von der Feldbreite. Die Zeichenfolge wird rechtsbündig in dem Feld ausgerichtet, wenn die Feldbreite ein positiver Wert ist, und linksbündig, wenn die Feldbreite ein negativer Wert ist. Im folgenden Beispiel werden Datumswerte in einem 20 Zeichen breiten Feld linksbündig ausgerichtet, und Dezimalwerte mit einer Hinterkommastelle werden in einem 11 Zeichen breiten Feld rechtsbündig ausgerichtet.

    DateTime startDate = new DateTime(2015, 8, 28, 6, 0, 0);
    decimal[] temps = { 73.452m, 68.98m, 72.6m, 69.24563m,
                       74.1m, 72.156m, 72.228m };
    Console.WriteLine("{0,-20} {1,11}\n", "Date", "Temperature");
    for (int ctr = 0; ctr < temps.Length; ctr++)
       Console.WriteLine("{0,-20:g} {1,11:N1}", startDate.AddDays(ctr), temps[ctr]);
    
    // The example displays the following output:
    //       Date                 Temperature
    //
    //       8/28/2015 6:00 AM           73.5
    //       8/29/2015 6:00 AM           69.0
    //       8/30/2015 6:00 AM           72.6
    //       8/31/2015 6:00 AM           69.2
    //       9/1/2015 6:00 AM            74.1
    //       9/2/2015 6:00 AM            72.2
    //       9/3/2015 6:00 AM            72.2
    
    Dim startDate As New Date(2015, 8, 28, 6, 0, 0)
    Dim temps() As Decimal = {73.452, 68.98, 72.6, 69.24563,
                               74.1, 72.156, 72.228}
    Console.WriteLine("{0,-20} {1,11}", "Date", "Temperature")
    Console.WriteLine()
    For ctr As Integer = 0 To temps.Length - 1
        Console.WriteLine("{0,-20:g} {1,11:N1}", startDate.AddDays(ctr), temps(ctr))
    Next
    ' The example displays the following output:
    '       Date                 Temperature
    '
    '       8/28/2015 6:00 AM           73.5
    '       8/29/2015 6:00 AM           69.0
    '       8/30/2015 6:00 AM           72.6
    '       8/31/2015 6:00 AM           69.2
    '       9/1/2015 6:00 AM            74.1
    '       9/2/2015 6:00 AM            72.2
    '       9/3/2015 6:00 AM            72.2
    

    Beachten Sie, dass, wenn sowohl die Ausrichtungszeichenfolge-Komponente als auch die Formatzeichenfolgen-Komponente vorhanden ist, die erste der letzteren vorausgeht (z. B. {0,-20:g}).

Weitere Informationen zur zusammengesetzten Formatierung finden Sie unter Kombinierte Formatierung.

Benutzerdefinierte Formatierung mit ICustomFormatter

Zwei Methoden zur kombinierten Formatierung, String.Format(IFormatProvider, String, Object[]) und StringBuilder.AppendFormat(IFormatProvider, String, Object[]), enthalten auch einen Formatanbieterparameter, der die benutzerdefinierte Formatierung unterstützt. Wenn eine der beiden Formatierungsmethoden aufgerufen wird, übergibt sie ein Type-Objekt, das eine ICustomFormatter-Schnittstelle für die GetFormat-Methode des Formatanbieters darstellt. Die GetFormat -Methode ist dann dafür verantwortlich, die ICustomFormatter -Implementierung zurückzugeben, die die benutzerdefinierte Formatierung bereitstellt.

Die ICustomFormatter -Schnittstelle verfügt über eine einzelne Methode, Format(String, Object, IFormatProvider), die für jedes Formatelement in einer zusammengesetzten Formatzeichenfolge automatisch von einer kombinierten Formatierungsmethode aufgerufen wird. Die Format(String, Object, IFormatProvider) -Methode verfügt über drei Parameter: eine Formatzeichenfolge, die das formatString -Argument in einem Formatelement darstellt, ein Objekt zum Formatieren und ein IFormatProvider -Objekt, das Formatierungsdienste bereitstellt. In der Regel implementiert die Klasse, die ICustomFormatter implementiert, auch IFormatProvider; der letzte Parameter stellt daher einen Verweis auf die benutzerdefinierte Formatierungsklasse selbst dar. Die Methode gibt eine benutzerdefinierte formatierte Zeichenfolgendarstellung des Objekts zurück, das formatiert werden soll. Wenn die Methode das Objekt nicht formatieren kann, sollte ein NULL-Verweis (Nothing in Visual Basic) zurückgegeben werden.

Im folgenden Beispiel wird eine ICustomFormatter -Implementierung mit dem Namen ByteByByteFormatter bereitgestellt, die ganzzahlige Werte als Sequenz von zweistelligen Hexadezimalwerten, gefolgt von einem Leerzeichen anzeigt.

public class ByteByByteFormatter : IFormatProvider, ICustomFormatter
{
   public object GetFormat(Type formatType)
   {
      if (formatType == typeof(ICustomFormatter))
         return this;
      else
         return null;
   }

   public string Format(string format, object arg,
                          IFormatProvider formatProvider)
   {
      if (! formatProvider.Equals(this)) return null;

      // Handle only hexadecimal format string.
      if (! format.StartsWith("X")) return null;

      byte[] bytes;
      string output = null;

      // Handle only integral types.
      if (arg is Byte)
         bytes = BitConverter.GetBytes((Byte) arg);
      else if (arg is Int16)
         bytes = BitConverter.GetBytes((Int16) arg);
      else if (arg is Int32)
         bytes = BitConverter.GetBytes((Int32) arg);
      else if (arg is Int64)
         bytes = BitConverter.GetBytes((Int64) arg);
      else if (arg is SByte)
         bytes = BitConverter.GetBytes((SByte) arg);
      else if (arg is UInt16)
         bytes = BitConverter.GetBytes((UInt16) arg);
      else if (arg is UInt32)
         bytes = BitConverter.GetBytes((UInt32) arg);
      else if (arg is UInt64)
         bytes = BitConverter.GetBytes((UInt64) arg);
      else
         return null;

      for (int ctr = bytes.Length - 1; ctr >= 0; ctr--)
         output += String.Format("{0:X2} ", bytes[ctr]);

      return output.Trim();
   }
}
Public Class ByteByByteFormatter : Implements IFormatProvider, ICustomFormatter
    Public Function GetFormat(formatType As Type) As Object _
                    Implements IFormatProvider.GetFormat
        If formatType Is GetType(ICustomFormatter) Then
            Return Me
        Else
            Return Nothing
        End If
    End Function

    Public Function Format(fmt As String, arg As Object,
                           formatProvider As IFormatProvider) As String _
                           Implements ICustomFormatter.Format

        If Not formatProvider.Equals(Me) Then Return Nothing

        ' Handle only hexadecimal format string.
        If Not fmt.StartsWith("X") Then
            Return Nothing
        End If

        ' Handle only integral types.
        If Not typeof arg Is Byte AndAlso
           Not typeof arg Is Int16 AndAlso
           Not typeof arg Is Int32 AndAlso
           Not typeof arg Is Int64 AndAlso
           Not typeof arg Is SByte AndAlso
           Not typeof arg Is UInt16 AndAlso
           Not typeof arg Is UInt32 AndAlso
           Not typeof arg Is UInt64 Then _
              Return Nothing

        Dim bytes() As Byte = BitConverter.GetBytes(arg)
        Dim output As String = Nothing

        For ctr As Integer = bytes.Length - 1 To 0 Step -1
            output += String.Format("{0:X2} ", bytes(ctr))
        Next

        Return output.Trim()
    End Function
End Class

Im folgenden Beispiel werden mit der ByteByByteFormatter -Klasse Ganzzahlwerte formatiert. Beachten Sie, dass die ICustomFormatter.Format -Methode im zweiten Aufruf der String.Format(IFormatProvider, String, Object[]) -Methode mehr als einmal aufgerufen wird, und dass der NumberFormatInfo -Standardanbieter im dritten Methodenaufruf verwendet wird, da dieByteByByteFormatter.Format -Methode die Formatzeichenfolge "N0" nicht erkennt und ein NULL-Verweis (Nothing in Visual Basic) ist.

public class Example10
{
   public static void Main()
   {
      long value = 3210662321;
      byte value1 = 214;
      byte value2 = 19;

      Console.WriteLine(String.Format(new ByteByByteFormatter(), "{0:X}", value));
      Console.WriteLine(String.Format(new ByteByByteFormatter(), "{0:X} And {1:X} = {2:X} ({2:000})",
                                      value1, value2, value1 & value2));
      Console.WriteLine(String.Format(new ByteByByteFormatter(), "{0,10:N0}", value));
   }
}
// The example displays the following output:
//       00 00 00 00 BF 5E D1 B1
//       00 D6 And 00 13 = 00 12 (018)
//       3,210,662,321
Public Module Example10
    Public Sub Main10()
        Dim value As Long = 3210662321
        Dim value1 As Byte = 214
        Dim value2 As Byte = 19

        Console.WriteLine((String.Format(New ByteByByteFormatter(), "{0:X}", value)))
        Console.WriteLine((String.Format(New ByteByByteFormatter(), "{0:X} And {1:X} = {2:X} ({2:000})",
                                        value1, value2, value1 And value2)))
        Console.WriteLine(String.Format(New ByteByByteFormatter(), "{0,10:N0}", value))
    End Sub
End Module
' The example displays the following output:
'       00 00 00 00 BF 5E D1 B1
'       00 D6 And 00 13 = 00 12 (018)
'       3,210,662,321
Titel Definition
Standard Numeric Format Strings Beschreibt als Standard verwendete Formatzeichenfolgen, mit denen häufig verwendete Zeichenfolgenentsprechungen von numerischen Werten erstellt werden.
Custom Numeric Format Strings Beschreibt benutzerdefinierte Formatzeichenfolgen, die anwendungsspezifische Formate für numerische Werte erstellen.
Standard Date and Time Format Strings Beschreibt als Standard verwendete Formatzeichenfolgen, mit denen häufig verwendete Zeichenfolgenentsprechungen von DateTime -Werten erstellt werden.
Custom Date and Time Format Strings Beschreibt benutzerdefinierte Formatzeichenfolgen, die anwendungsspezifische Formate für DateTime -Werte erstellen.
TimeSpan-Standardformatzeichenfolgen Beschreibt als Standard verwendete Formatzeichenfolgen, mit denen häufig verwendete Zeichenfolgenentsprechungen von Zeitintervallen erstellt werden.
Benutzerdefinierte TimeSpan-Formatzeichenfolgen Beschreibt benutzerdefinierte Formatzeichenfolgen, die anwendungsspezifische Formate für Zeitintervalle erstellen.
Enumeration Format Strings Beschreibt als Standard verwendete Formatzeichenfolgen, mit denen Zeichenfolgenentsprechungen von Enumerationswerten erstellt werden.
Kombinierte Formatierung Beschreibt die Einbettung eines oder mehrerer formatierter Werte in eine Zeichenfolge. Die Zeichenfolge kann anschließend in der Konsole angezeigt oder in einen Stream geschrieben werden.
Analysieren von Zeichenfolgen in .NET Beschreibt, wie Objekte mit den Werten initialisiert werden, die durch Zeichenfolgenentsprechungen dieser Objekte beschrieben werden. Das Verarbeiten ist die Umkehroperation zum Formatieren.

Referenz