Kombinierte Formatierung

Die Funktion für die kombinierte Formatierung in .NET verwendet als Eingabe eine Liste von Objekten und eine kombinierte Formatzeichenfolge. Eine kombinierte Formatzeichenfolge besteht aus festgelegtem Text mit indizierten Platzhaltern, so genannten Formatelementen, die den Objekten in der Liste entsprechen. Der Formatierungsvorgang liefert eine Ergebniszeichenfolge, die sich aus dem ursprünglichen festgelegten Text und der Zeichenfolgendarstellung der Objekte in der Liste zusammensetzt.

Wichtig

Anstelle kombinierter Formatzeichenfolgen können Sie interpolierte Zeichenfolgen verwenden, wenn die von Ihnen verwendete Sprache und Version diese unterstützen. Eine interpolierte Zeichenfolge enthält interpolierte Ausdrücke. Jeder interpolierte Ausdruck wird mit dem Wert des Ausdrucks aufgelöst und in die Ergebniszeichenfolge aufgenommen, wenn die Zeichenfolge zugewiesen wird. Weitere Informationen finden Sie unter Zeichenfolgeninterpolation (C#-Referenz) und Interpolierte Zeichenfolgen (Visual Basic-Referenz).

Die folgenden Methoden unterstützen das zusammengesetzte Formatierungsfeature:

Kombinierte Formatzeichenfolge

Eine kombinierte Formatzeichenfolge und eine Objektliste dienen als Argumente von Methoden, die das Feature für die kombinierte Formatierung unterstützen. Die Quellzeichenfolge besteht aus 0 (null) oder mehreren Einheiten festgelegten Texts mit mindestens einem Formatelement. Der festgelegte Text ist eine von Ihnen ausgewählte beliebige Zeichenfolge. Jedes Formatelement entspricht einem Objekt oder einer geschachtelten Struktur in der Liste. Die Zeichenfolgendarstellung jedes Objekts ersetzt das entsprechende Formatelement.

Betrachten Sie das folgende Format-Codefragment:

string.Format("Name = {0}, hours = {1:hh}", "Fred", DateTime.Now);
String.Format("Name = {0}, hours = {1:hh}", "Fred", DateTime.Now)

Der feste Text ist Name = und , hours = . Die Formatelemente sind {0}, dessen Index 0 dem Objekt name entspricht, und {1:hh}, dessen Index 1 dem Objekt DateTime.Now entspricht.

Formatelementsyntax

Alle Formatelemente weisen die folgende Form auf und bestehen aus folgenden Komponenten:

{index[,alignment][:formatString]}

Die übereinstimmenden geschweiften Klammern ({ und }) sind erforderlich.

Indexkomponente

Bei der obligatorischen Komponente Index, dem sogenannten Parameterbezeichner, handelt es sich um eine bei 0 (null) beginnende Zahl, mit der ein entsprechendes Element in der Objektliste angegeben wird. Das bedeutet, dass das Formatelement mit dem Parameterbezeichner 0 das erste Objekt in der Liste formatiert. Das Formatelement mit dem Parameterbezeichner 1 formatiert das zweite Objekt in der Liste usw. Das folgende Beispiel enthält vier von null bis drei nummerierte Parameterbezeichner zur Darstellung von Primzahlen, die kleiner als 10 sind:

string.Format("Name = {0}, hours = {1:hh}", "Fred", DateTime.Now);
String.Format("Name = {0}, hours = {1:hh}", "Fred", DateTime.Now)

Mehrere Formatelemente können auf dasselbe Element in der Objektliste verweisen, indem derselbe Parameterbezeichner festgelegt wird. Sie können beispielsweise denselben numerischen Wert im hexadezimalen, wissenschaftlichen oder Zahlenformat formatieren, indem Sie eine kombinierte Formatierungszeichenfolge wie „"0x{0:X} {0:E} {0:N}"“ angeben, wie im folgenden Beispiel gezeigt:

string multiple = string.Format("0x{0:X} {0:E} {0:N}",
                                Int64.MaxValue);
Console.WriteLine(multiple);

// The example displays the following output:
//      0x7FFFFFFFFFFFFFFF 9.223372E+018 9,223,372,036,854,775,807.00
Dim multiple As String = String.Format("0x{0:X} {0:E} {0:N}",
                                       Int64.MaxValue)
Console.WriteLine(multiple)

'The example displays the following output
'     0x7FFFFFFFFFFFFFFF 9.223372E+018 9,223,372,036,854,775,807.00

Jedes Formatelement kann auf ein beliebiges Objekt in der Liste verweisen. Wenn beispielsweise drei Objekte vorliegen, können Sie das zweite, erste und dritte Objekt formatieren, indem Sie eine kombinierte Formatzeichenfolge wie „{1} {0} {2}“ angeben. Ein Objekt, auf das kein Formatelement verweist, wird ignoriert. Eine FormatException wird zur Laufzeit ausgelöst, wenn ein Parameterbezeichner auf ein Element außerhalb der Grenzen der Objektliste verweist.

Ausrichtungskomponente

Bei der optionalen Komponente Ausrichtung handelt es sich um eine ganze Zahl mit Vorzeichen, die die gewünschte formatierte Feldbreite angibt. Wenn der Wert für Ausrichtung kleiner als die Länge der formatierten Zeichenfolge ist, wird Ausrichtung ignoriert, und die Länge der formatierten Zeichenfolge wird als Feldbreite verwendet. Die formatierten Daten im Feld werden bei einem positiven Wert für Ausrichtung rechtsbündig und bei einem negativen Wert für Ausrichtung linksbündig ausgerichtet. Wenn Füllzeichen erforderlich sind, werden Leerräume verwendet. Das Komma ist erforderlich, wenn Ausrichtung angegeben wird.

Im folgenden Beispiel werden zwei Arrays definiert, ein Array mit den Namen der Mitarbeiter und ein Array mit den Arbeitsstunden der Mitarbeiter über einen Zeitraum von zwei Wochen. Die kombinierte Formatzeichenfolge richtet die Namen in einem Feld mit 20 Zeichen linksbündig aus, und die Stunden werden in einem Feld mit 5 Zeichen rechtsbündig ausgerichtet. Die Standardformatzeichenfolge „N1“ formatiert die Stunden mit einer Dezimalstelle.

string[] names = { "Adam", "Bridgette", "Carla", "Daniel",
                   "Ebenezer", "Francine", "George" };
decimal[] hours = { 40, 6.667m, 40.39m, 82,
                    40.333m, 80, 16.75m };

Console.WriteLine("{0,-20} {1,5}\n", "Name", "Hours");

for (int counter = 0; counter < names.Length; counter++)
    Console.WriteLine("{0,-20} {1,5:N1}", names[counter], hours[counter]);

// The example displays the following output:
//      Name                 Hours
//      
//      Adam                  40.0
//      Bridgette              6.7
//      Carla                 40.4
//      Daniel                82.0
//      Ebenezer              40.3
//      Francine              80.0
//      George                16.8
Dim names As String() = {"Adam", "Bridgette", "Carla", "Daniel",
                         "Ebenezer", "Francine", "George"}

Dim hours As Decimal() = {40, 6.667D, 40.39D, 82,
                          40.333D, 80, 16.75D}

Console.WriteLine("{0,-20} {1,5}\n", "Name", "Hours")

For counter = 0 To names.Length - 1
    Console.WriteLine("{0,-20} {1,5:N1}", names(counter), hours(counter))
Next

'The example displays the following output
'     Name                 Hours
'     
'     Adam                  40.0
'     Bridgette              6.7
'     Carla                 40.4
'     Daniel                82.0
'     Ebenezer              40.3
'     Francine              80.0
'     George                16.8

Formatzeichenfolgenkomponente

Die optionale Komponente Formatzeichenfolge ist eine Formatzeichenfolge, die für den Objekttyp geeignet ist, der formatiert wird. Sie können Folgendes angeben:

  • Eine standardmäßige oder benutzerdefinierte numerische Formatzeichenfolge, wenn das entsprechende Objekt ein numerischer Wert ist
  • Eine standardmäßige oder benutzerdefinierte Formatzeichenfolge für Datum und Uhrzeit, wenn das entsprechende Objekt ein DateTime-Objekt ist
  • Eine Enumerationsformatzeichenfolge, wenn das entsprechende Objekt ein Enumerationswert ist

Wenn Formatzeichenfolge nicht festgelegt ist, wird der allgemeine Formatbezeichner („G“) für einen numerischen, einen Datums- und Uhrzeit- oder einen Enumerationstyp verwendet. Der Doppelpunkt ist erforderlich, wenn Formatzeichenfolge angegeben wird.

Die folgende Tabelle listet Typen oder Kategorien von Typen in der .NET-Klassenbibliothek auf, die mehrere vordefinierte Formatzeichenfolgen unterstützen, und stellt Links zu den Artikeln bereit, die diese unterstützten Formatzeichenfolgen auflisten. Die Zeichenfolgenformatierung ist ein erweiterbarer Mechanismus, der es ermöglicht, neue Formatzeichenfolgen für alle vorhandenen Typen zu definieren und Formatzeichenfolgen zu definieren, der von einem anwendungsdefinierten Typ unterstützt wird.

Weitere Informationen finden Sie in den Artikeln zu den Schnittstellen IFormattable und ICustomFormatter.

Typ oder Typkategorie Siehe
Datums-/Zeittypen (DateTime, DateTimeOffset) Standard-Formatzeichenfolgen für Datum und Uhrzeit

Benutzerdefinierte Formatzeichenfolgen für Datum und Uhrzeit
Enumerationstypen (alle Typen abgeleitet von System.Enum) Enumerationsformatzeichenfolgen
Numerische Typen (BigInteger, Byte, Decimal, Double, Int16, Int32, Int64, SByte, Single, UInt16, UInt32, UInt64) Standardmäßige Zahlenformatzeichenfolgen

Benutzerdefinierte Zahlenformatzeichenfolgen
Guid Guid.ToString(String)
TimeSpan TimeSpan-Standardformatzeichenfolgen

Benutzerdefinierte TimeSpan-Formatzeichenfolgen

Versehen von geschweiften Klammern mit Escapezeichen

Öffnende und schließende geschweifte Klammern werden als Beginn und Ende eines Formatelements interpretiert. Um eine literale öffnende bzw. schließende geschweifte Klammer anzuzeigen, müssen Sie eine Escapesequenz verwenden. Geben Sie zwei öffnende geschweifte Klammern ({{) im festgelegten Text an, um eine öffnende geschweifte Klammer ({) anzuzeigen, oder geben Sie zwei schließende geschweifte Klammern (}}) an, um eine schließende geschweifte Klammer (}) anzuzeigen.

Escapeklammern mit einem Formatelement werden zwischen .NET und .NET Framework unterschiedlich analysiert.

.NET

Geschweifte Klammern können um ein Formatelement herum mit Escapezeichen versehen werden. Betrachten Sie beispielsweise das Formatelement {{{0:D}}}, das eine öffnende geschweifte Klammer, einen numerischen Wert, der als Dezimalzahl formatiert ist, und eine schließende geschweifte Klammer anzeigen soll. Das Formatelement wird wie folgt interpretiert:

  1. Die ersten beiden öffnenden geschweiften Klammern ({{) werden mit Escapezeichen versehen und ergeben eine öffnende geschweifte Klammer.
  2. Die nächsten drei Zeichen ({0:) werden als Anfang eines Formatelements interpretiert.
  3. Das nächste Zeichen (D) wird als numerischer Dezimalformatbezeichner interpretiert.
  4. Die nächste geschweifte Klammer (}) wird als Ende des Formatelements interpretiert.
  5. Die letzten beiden schließenden geschweiften Klammern werden mit Escapezeichen versehen und ergeben eine schließende geschweifte Klammer.
  6. Das Endergebnis, das angezeigt wird, ist die Literalzeichenfolge {6324}.
int value = 6324;
string output = string.Format("{{{0:D}}}", value);

Console.WriteLine(output);
// The example displays the following output:
//       {6324}
Dim value As Integer = 6324
Dim output As String = String.Format("{{{0:D}}}", value)

Console.WriteLine(output)

'The example displays the following output
'      {6324}

.NET Framework

Geschweifte Klammern in einem Formatelement werden sequenziell in der Reihenfolge interpretiert, in der sie gefunden werden. Die Interpretation geschachtelter geschweifter Klammern wird nicht unterstützt.

Die Art und Weise, wie geschweifte Klammern mit Escapezeichen interpretiert werden, kann zu unerwarteten Ergebnissen führen. Betrachten Sie beispielsweise das Formatelement {{{0:D}}}, das eine öffnende geschweifte Klammer, einen numerischen Wert, der als Dezimalzahl formatiert ist, und eine schließende geschweifte Klammer anzeigen soll. Das Formatelement wird aber wie folgt interpretiert:

  1. Die ersten beiden öffnenden geschweiften Klammern ({{) werden mit Escapezeichen versehen und ergeben eine öffnende geschweifte Klammer.
  2. Die nächsten drei Zeichen ({0:) werden als Anfang eines Formatelements interpretiert.
  3. Das nächste Zeichen (D) wird als Formatbezeichner für das numerische Standarddezimalformat interpretiert, und die nächsten beiden geschweiften Klammern mit Escapezeichen (}}) ergeben eine einzelne geschweifte Klammer. Da die entstehende Zeichenfolge (D}) kein numerischer Standardformatbezeichner ist, wird sie als benutzerdefinierte Formatzeichenfolge interpretiert, d. h., es wird die Literalzeichenfolge D} angezeigt.
  4. Die letzte geschweifte Klammer (}) wird als Ende des Formatelements interpretiert.
  5. Das Endergebnis, das angezeigt wird, ist die Literalzeichenfolge {D}. Der numerische Wert, der formatiert werden sollte, wird nicht angezeigt.
int value = 6324;
string output = string.Format("{{{0:D}}}",
                              value);
Console.WriteLine(output);

// The example displays the following output:
//       {D}
Dim value As Integer = 6324
Dim output As String = String.Format("{{{0:D}}}",
                                     value)
Console.WriteLine(output)

'The example displays the following output:
'      {D}

Eine Möglichkeit, Code zu schreiben und dabei Probleme mit falsch interpretierten geschweiften Klammern und Formatelementen zu vermeiden, ist die separate Formatierung der geschweiften Klammern und Formatelemente. Zeigen Sie daher im ersten Formatvorgang eine literale öffnende geschweifte Klammer, im nächsten Formatierungsvorgang das Ergebnis des Formatelements und letzten Formatierungsvorgang eine literale schließende geschweifte Klammer an. Dieser Ansatz wird im folgenden Beispiel veranschaulicht:

int value = 6324;
string output = string.Format("{0}{1:D}{2}",
                             "{", value, "}");
Console.WriteLine(output);

// The example displays the following output:
//       {6324}
Dim value As Integer = 6324
Dim output As String = String.Format("{0}{1:D}{2}",
                                     "{", value, "}")
Console.WriteLine(output)

'The example displays the following output:
'      {6324}

Verarbeitungsreihenfolge

Wenn der Aufruf der Methode für die kombinierte Formatierung ein IFormatProvider-Argument enthält, dessen Wert nicht null ist, ruft die Runtime die IFormatProvider.GetFormat-Methode auf, um eine ICustomFormatter-Implementierung anzufordern. Wenn die Methode eine ICustomFormatter-Implementierung zurückgeben kann, wird diese während des Aufrufs der Methode für die kombinierte Formatierung zwischengespeichert.

Jeder Wert in der Parameterliste, der einem Formatelement entspricht, wird wie folgt in eine Zeichenfolge konvertiert:

  1. Wenn der zu formatierende Wert null ist, wird eine leere Zeichenfolge (String.Empty) zurückgegeben.

  2. Wenn eine ICustomFormatter-Implementierung verfügbar ist, ruft die Laufzeit die Format-Methode auf. Die Runtime übergibt den formatString-Wert des Formatelements (oder null, wenn das Element nicht vorhanden ist) an die Methode. Außerdem übergibt die Runtime die IFormatProvider-Implementierung an die Methode. Wenn durch den Aufruf der ICustomFormatter.Format-Methode null zurückgegeben wird, wird der nächste Schritt ausgeführt. Andernfalls wird das Ergebnis des ICustomFormatter.Format-Aufrufs zurückgegeben.

  3. Wenn der Wert die IFormattable-Schnittstelle implementiert, wird die ToString(String, IFormatProvider)-Methode der Schnittstelle aufgerufen. Der Formatzeichenfolge-Wert wird, sofern im Formatelement vorhanden, an die Methode übergeben. Ist dies nicht der Fall, wird null übergeben. Das IFormatProvider-Argument wird wie folgt bestimmt:

  4. Die parameterlose ToString-Methode des Typs, die entweder Object.ToString() überschreibt oder das Verhalten ihrer Basisklasse erbt, wird aufgerufen. In diesem Fall wird die von der formatString-Komponente im Formatelement angegebene Formatzeichenfolge (sofern vorhanden) ignoriert.

Die Ausrichtung wird angewendet, nachdem die vorhergehenden Schritte durchgeführt wurden.

Codebeispiele

Das folgende Beispiel stellt eine Zeichenfolge dar, die mit der kombinierten Formatierung erstellt wurde, und eine weitere, die mit der ToString-Methode eines Objekts erstellt wurde. Beide Formatierungen führen zum gleichen Ergebnis.

string formatString1 = string.Format("{0:dddd MMMM}", DateTime.Now);
string formatString2 = DateTime.Now.ToString("dddd MMMM");
Dim formatString1 As String = String.Format("{0:dddd MMMM}", DateTime.Now)
Dim formatString2 As String = DateTime.Now.ToString("dddd MMMM")

Wenn das aktuelle Datum ein Donnerstag im Mai ist, lautet der Wert beider Zeichenfolgen im vorherigen Beispiel Thursday May in der Kultur Englisch (USA).

Console.WriteLine stellt die gleiche Funktionalität wie String.Format bereit. Der einzige Unterschied zwischen den beiden Methoden besteht darin, dass String.Format das Ergebnis als Zeichenfolge zurückgibt, während Console.WriteLine das Ergebnis in den Ausgabestrom schreibt, der dem Console-Objekt zugeordnet ist. Im folgenden Beispiel wird der Wert von myNumber mit der Console.WriteLine-Methode als Währungswert formatiert:

int myNumber = 100;
Console.WriteLine("{0:C}", myNumber);

// The example displays the following output
// if en-US is the current culture:
//        $100.00
Dim myNumber As Integer = 100
Console.WriteLine("{0:C}", myNumber)

'The example displays the following output
'if en-US Is the current culture:
'       $100.00

Im folgenden Beispiel wird die Formatierung mehrerer Objekte veranschaulicht, wobei ein Objekt auf zwei Arten formatiert wird:

string myName = "Fred";
Console.WriteLine(string.Format("Name = {0}, hours = {1:hh}, minutes = {1:mm}",
                                myName, DateTime.Now));

// Depending on the current time, the example displays output like the following:
//        Name = Fred, hours = 11, minutes = 30
Dim myName As String = "Fred"
Console.WriteLine(String.Format("Name = {0}, hours = {1:hh}, minutes = {1:mm}",
                                myName, DateTime.Now))
'Depending on the current time, the example displays output Like the following:
'       Name = Fred, hours = 11, minutes = 30

Das folgende Beispiel veranschaulicht die Verwendung der Ausrichtung beim Formatieren. Die zu formatierenden Argumente werden zwischen senkrechte Striche (|) platziert, um die resultierende Ausrichtung zu kennzeichnen.

string firstName = "Fred";
string lastName = "Opals";
int myNumber = 100;

string formatFirstName = string.Format("First Name = |{0,10}|", firstName);
string formatLastName = string.Format("Last Name =  |{0,10}|", lastName);
string formatPrice = string.Format("Price =      |{0,10:C}|", myNumber);
Console.WriteLine(formatFirstName);
Console.WriteLine(formatLastName);
Console.WriteLine(formatPrice);
Console.WriteLine();

formatFirstName = string.Format("First Name = |{0,-10}|", firstName);
formatLastName = string.Format("Last Name =  |{0,-10}|", lastName);
formatPrice = string.Format("Price =      |{0,-10:C}|", myNumber);
Console.WriteLine(formatFirstName);
Console.WriteLine(formatLastName);
Console.WriteLine(formatPrice);

// The example displays the following output on a system whose current
// culture is en-US:
//     First Name = |      Fred|
//     Last Name =  |     Opals|
//     Price =      |   $100.00|
//
//     First Name = |Fred      |
//     Last Name =  |Opals     |
//     Price =      |$100.00   |
Dim firstName As String = "Fred"
Dim lastName As String = "Opals"
Dim myNumber As Integer = 100

Dim formatFirstName As String = String.Format("First Name = |{0,10}|", firstName)
Dim formatLastName As String = String.Format("Last Name =  |{0,10}|", lastName)
Dim formatPrice As String = String.Format("Price =      |{0,10:C}|", myNumber)
Console.WriteLine(formatFirstName)
Console.WriteLine(formatLastName)
Console.WriteLine(formatPrice)
Console.WriteLine()

formatFirstName = String.Format("First Name = |{0,-10}|", firstName)
formatLastName = String.Format("Last Name =  |{0,-10}|", lastName)
formatPrice = String.Format("Price =      |{0,-10:C}|", myNumber)
Console.WriteLine(formatFirstName)
Console.WriteLine(formatLastName)
Console.WriteLine(formatPrice)

'The example displays the following output on a system whose current
'culture Is en-US:
'    First Name = |      Fred|
'    Last Name =  |     Opals|
'    Price =      |   $100.00|
'
'    First Name = |Fred      |
'    Last Name =  |Opals     |
'    Price =      |$100.00   |

Siehe auch