System.String.Format-Methode

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

Wichtig

Statt die Methode String.Format aufzurufen oder Zeichenfolgen mit kombinierter Formatierung zu verwenden, können Sie interpolierte Zeichenfolgen verwenden, wenn diese von Ihrer Sprache unterstützt werden. Eine interpolierte Zeichenfolge ist eine Zeichenfolge, die interpolierte Ausdrücke enthält. 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).

Beispiele

In diesem Artikel werden zahlreiche Beispiele zum Aufrufen der Format Methode interspersiert. Sie können auch einen vollständigen Satz von String.Format Beispielen herunterladen, die ein .NET Core-Projekt für C# enthalten.

Im Folgenden finden Sie einige der Beispiele, die im Artikel enthalten sind:

Erstellen einer Formatzeichenfolge

Einfügen einer Zeichenfolge
Das Formatelement
Formatieren von Elementen mit demselben Index

Formatierte Ausgabe steuern

Steuerelementformatierung
Steuern des Abstands
Steuerelementausrichtung
Steuern der Anzahl der integralen Ziffern
Steuern der Anzahl von Ziffern nach dem Dezimaltrennzeichen
Schließen Sie literale geschweifte Klammern in die Ergebniszeichenfolge ein.

Formatzeichenfolgen kulturempfindlich machen

Formatzeichenfolgen kulturempfindlich machen

Anpassen des Formatierungsvorgangs

Ein benutzerdefinierter Formatierungsvorgang
Ein Achsenabschnittsanbieter und ein römischer Zahlenformatierer

Erste Schritte mit der String.Format-Methode

Verwenden Sie String.Format diesen Wert, wenn Sie den Wert eines Objekts, einer Variablen oder eines Ausdrucks in eine andere Zeichenfolge einfügen müssen. Sie können beispielsweise den Wert eines Decimal Werts in eine Zeichenfolge einfügen, um ihn dem Benutzer als einzelne Zeichenfolge anzuzeigen:

Decimal pricePerOunce = 17.36m;
String s = String.Format("The current price is {0} per ounce.",
                         pricePerOunce);
Console.WriteLine(s);
// Result: The current price is 17.36 per ounce.
let pricePerOunce = 17.36m
String.Format("The current price is {0} per ounce.", pricePerOunce)
|> printfn "%s"
// Result: The current price is 17.36 per ounce.
Dim pricePerOunce As Decimal = 17.36D
Dim s As String = String.Format("The current price is {0} per ounce.",
                              pricePerOunce)
' Result: The current price is 17.36 per ounce.

Und Sie können die Formatierung dieses Werts steuern:

Decimal pricePerOunce = 17.36m;
String s = String.Format("The current price is {0:C2} per ounce.",
                         pricePerOunce);
Console.WriteLine(s);
// Result if current culture is en-US:
//      The current price is $17.36 per ounce.
let pricePerOunce = 17.36m
String.Format("The current price is {0:C2} per ounce.", pricePerOunce)
|> printfn "%s"
// Result if current culture is en-US:
//      The current price is $17.36 per ounce.
Dim pricePerOunce As Decimal = 17.36D
Dim s As String = String.Format("The current price is {0:C2} per ounce.",
                              pricePerOunce)
' Result if current culture is en-US:
'      The current price is $17.36 per ounce.

Neben der Formatierung können Sie auch die Ausrichtung und den Abstand steuern.

Einfügen einer Zeichenfolge

String.Format beginnt mit einer Formatzeichenfolge, gefolgt von einem oder mehreren Objekten oder Ausdrücken, die in Zeichenfolgen konvertiert und an einer bestimmten Stelle in der Formatzeichenfolge eingefügt werden. Zum Beispiel:

decimal temp = 20.4m;
string s = String.Format("The temperature is {0}°C.", temp);
Console.WriteLine(s);
// Displays 'The temperature is 20.4°C.'
let temp = 20.4m
String.Format("The temperature is {0}°C.", temp)
|> printfn "%s"
// Displays 'The temperature is 20.4°C.'
Dim temp As Decimal = 20.4D
Dim s As String = String.Format("The temperature is {0}°C.", temp)
Console.WriteLine(s)
' Displays 'The temperature is 20.4°C.'

Bei {0} der Formatzeichenfolge handelt es sich um ein Formatelement. 0 ist der Index des Objekts, dessen Zeichenfolgenwert an dieser Position eingefügt wird. (Indizes beginnen bei 0.) Wenn das einzufügende Objekt keine Zeichenfolge ist, wird die ToString Methode aufgerufen, um es in eine zu konvertieren, bevor es in die Ergebniszeichenfolge eingefügt wird.

Hier ist ein weiteres Beispiel, das zwei Formatelemente und zwei Objekte in der Objektliste verwendet:

string s = String.Format("At {0}, the temperature is {1}°C.",
                         DateTime.Now, 20.4);
Console.WriteLine(s);
// Output similar to: 'At 4/10/2015 9:29:41 AM, the temperature is 20.4°C.'
String.Format("At {0}, the temperature is {1}°C.", DateTime.Now, 20.4)
|> printfn "%s"
// Output similar to: 'At 4/10/2015 9:29:41 AM, the temperature is 20.4°C.'
Dim s As String = String.Format("At {0}, the temperature is {1}°C.",
                              Date.Now, 20.4)
' Output similar to: 'At 4/10/2015 9:29:41 AM, the temperature is 20.4°C.'

Sie können beliebig viele Formatelemente und beliebig viele Objekte in der Objektliste haben, solange der Index jedes Formatelements ein übereinstimmende Objekt in der Objektliste aufweist. Sie müssen sich auch keine Gedanken darüber machen, welche Überladung Sie anrufen; der Compiler wählt die entsprechende für Sie aus.

Steuerelementformatierung

Sie können dem Index in einem Formatelement mit einer Formatzeichenfolge folgen, um zu steuern, wie ein Objekt formatiert wird. Wendet beispielsweise {0:d} die Formatzeichenfolge "d" auf das erste Objekt in der Objektliste an. Hier ist ein Beispiel mit einem einzelnen Objekt und zwei Formatelementen:

string s = String.Format("It is now {0:d} at {0:t}", DateTime.Now);
Console.WriteLine(s);
// Output similar to: 'It is now 4/10/2015 at 10:04 AM'
String.Format("It is now {0:d} at {0:t}", DateTime.Now)
|> printfn "%s"
// Output similar to: 'It is now 4/10/2015 at 10:04 AM'
Dim s As String = String.Format("It is now {0:d} at {0:t}",
                              Date.Now)
' Output similar to: 'It is now 4/10/2015 at 10:04 AM'

Eine Reihe von Typen unterstützt Formatzeichenfolgen, einschließlich aller numerischen Typen (sowohl Standard- als auch benutzerdefinierte Formatzeichenfolgen), alle Datums- und Uhrzeitangaben (sowohl Standard- als auch benutzerdefinierte Formatzeichenfolgen) und Zeitintervalle (sowohl Standard- als auch benutzerdefinierte Formatzeichenfolgen), alle Enumerationstypen enumerationstypen und GUIDs. Sie können auch Unterstützung für das Format von Zeichenfolgen zu Ihren eigenen Typen hinzufügen.

Steuern des Abstands

Sie können die Breite der Zeichenfolge definieren, die in die Ergebniszeichenfolge eingefügt wird, indem Sie eine Syntax wie {0,12}z. B. eine 12-stellige Zeichenfolge einfügen. In diesem Fall wird die Zeichenfolgendarstellung des ersten Objekts im 12-Zeichen-Feld rechtsbündig ausgerichtet. (Wenn die Zeichenfolgendarstellung des ersten Objekts mehr als 12 Zeichen lang ist, wird die bevorzugte Feldbreite jedoch ignoriert, und die gesamte Zeichenfolge wird in die Ergebniszeichenfolge eingefügt.)

Im folgenden Beispiel wird ein 6-stelliges Feld definiert, das die Zeichenfolge "Year" und einige Jahreszeichenfolgen enthält, sowie ein 15-stelliges Feld, das die Zeichenfolge "Population" und einige Populationsdaten enthält. Beachten Sie, dass die Zeichen im Feld rechtsbündig ausgerichtet sind.

int[] years = { 2013, 2014, 2015 };
int[] population = { 1025632, 1105967, 1148203 };
var sb = new System.Text.StringBuilder();
sb.Append(String.Format("{0,6} {1,15}\n\n", "Year", "Population"));
for (int index = 0; index < years.Length; index++)
    sb.Append(String.Format("{0,6} {1,15:N0}\n", years[index], population[index]));

Console.WriteLine(sb);

// Result:
//      Year      Population
//
//      2013       1,025,632
//      2014       1,105,967
//      2015       1,148,203
open System
open System.Text
 
let years = [| 2013; 2014; 2015 |]
let population = [| 1025632; 1105967; 1148203 |]
let sb = StringBuilder()
sb.Append(String.Format("{0,6} {1,15}\n\n", "Year", "Population")) |> ignore
for i = 0 to years.Length - 1 do
   sb.Append(String.Format("{0,6} {1,15:N0}\n", years[i], population[i])) |> ignore

printfn $"{sb}"

// Result:
//      Year      Population
//
//      2013       1,025,632
//      2014       1,105,967
//      2015       1,148,203
Dim years() As Integer = {2013, 2014, 2015}
Dim population() As Integer = {1025632, 1105967, 1148203}
Dim sb As New StringBuilder()
sb.Append(String.Format("{0,6} {1,15}{2}{2}",
                       "Year", "Population", vbCrLf))
For index As Integer = 0 To years.Length - 1
    sb.AppendFormat("{0,6} {1,15:N0}{2}",
                  years(index), population(index), vbCrLf)
Next
' Result:
'      Year      Population
'
'      2013       1,025,632
'      2014       1,105,967
'      2015       1,148,203

Steuerelementausrichtung

Standardmäßig werden Zeichenfolgen innerhalb ihres Felds rechtsbündig ausgerichtet, wenn Sie eine Feldbreite angeben. Wenn Sie Zeichenfolgen in einem Feld linksbündig ausrichten möchten, stellen Sie der Feldbreite ein negatives Zeichen voran, z {0,-12} . B. zum Definieren eines linksbündigen Felds mit 12 Zeichen.

Das folgende Beispiel ähnelt dem vorherigen, mit der Ausnahme, dass es sowohl Beschriftungen als auch Daten linksbündig ausgerichtet ist.

int[] years = { 2013, 2014, 2015 };
int[] population = { 1025632, 1105967, 1148203 };
String s = String.Format("{0,-10} {1,-10}\n\n", "Year", "Population");
for (int index = 0; index < years.Length; index++)
    s += String.Format("{0,-10} {1,-10:N0}\n",
                       years[index], population[index]);
Console.WriteLine($"\n{s}");
// Result:
//    Year       Population
//
//    2013       1,025,632
//    2014       1,105,967
//    2015       1,148,203
let years = [| 2013; 2014; 2015 |]
let population = [| 1025632; 1105967; 1148203 |]
let mutable s = String.Format("{0,-10} {1,-10}\n\n", "Year", "Population")
for i = 0 to years.Length - 1 do
    s <- s + String.Format("{0,-10} {1,-10:N0}\n", years[i], population[i])
printfn $"\n{s}"
// Result:
//    Year       Population
//
//    2013       1,025,632
//    2014       1,105,967
//    2015       1,148,203
Dim years() As Integer = {2013, 2014, 2015}
Dim population() As Integer = {1025632, 1105967, 1148203}
Dim s As String = String.Format("{0,-10} {1,-10}{2}{2}",
                               "Year", "Population", vbCrLf)
For index As Integer = 0 To years.Length - 1
    s += String.Format("{0,-10} {1,-10:N0}{2}",
                     years(index), population(index), vbCrLf)
Next
' Result:
'    Year       Population
'
'    2013       1,025,632
'    2014       1,105,967
'    2015       1,148,203

String.Format verwendet das Zusammengesetztformatierungsfeature. Weitere Informationen finden Sie unter Zusammengesetzte Formatierung.

Welche Methode wird aufgerufen?

Beschreibung Call
Formatieren Sie ein oder mehrere Objekte mithilfe der Konventionen der aktuellen Kultur. Mit Ausnahme der Überladungen, die einen provider Parameter enthalten, enthalten die Re Standard ing-Überladungen Format einen String Parameter, gefolgt von einem oder mehreren Objektparametern. Aus diesem Gründen müssen Sie nicht bestimmen, welche Format Überladung Sie aufrufen möchten. Der Sprachcompiler wählt die entsprechende Überladung aus den Überladungen aus, die nicht über einen provider Parameter verfügen, basierend auf der Argumentliste. Wenn ihre Argumentliste beispielsweise fünf Argumente enthält, ruft der Compiler die Format(String, Object[]) Methode auf.
Formatieren Sie ein oder mehrere Objekte mithilfe der Konventionen einer bestimmten Kultur. Jede Format Überladung, die mit einem provider Parameter beginnt, folgt einem String Parameter und einem oder mehreren Objektparametern. Aus diesem Gründen müssen Sie nicht bestimmen, welche bestimmte Format Überladung Sie aufrufen möchten. Der Sprachcompiler wählt die entsprechende Überladung aus den Überladungen aus, die basierend auf der Argumentliste einen provider Parameter aufweisen. Wenn ihre Argumentliste beispielsweise fünf Argumente enthält, ruft der Compiler die Format(IFormatProvider, String, Object[]) Methode auf.
Führen Sie einen benutzerdefinierten Formatierungsvorgang entweder mit einer ICustomFormatter Implementierung oder einer IFormattable Implementierung aus. Eine der vier Überladungen mit einem provider Parameter. Der Compiler wählt die entsprechende Überladung aus den Überladungen aus, die einen provider Parameter aufweisen, basierend auf der Argumentliste.

Die Format-Methode kurz

Jede Überladung der Format Methode verwendet das zusammengesetzte Formatierungsfeature, um nullbasierte indizierte Platzhalter, die als Formatelemente bezeichnet werden, in eine zusammengesetzte Formatzeichenfolge einzuschließen. Zur Laufzeit wird jedes Formatelement durch die Zeichenfolgendarstellung des entsprechenden Arguments in einer Parameterliste ersetzt. Wenn der Wert des Arguments lautet null, wird das Formatelement durch String.Empty. Beispielsweise enthält der folgende Aufruf der Format(String, Object, Object, Object) Methode eine Formatzeichenfolge mit drei Formatelementen, {0}, {1}und {2}eine Argumentliste mit drei Elementen.

DateTime dat = new DateTime(2012, 1, 17, 9, 30, 0); 
string city = "Chicago";
int temp = -16;
string output = String.Format("At {0} in {1}, the temperature was {2} degrees.",
                              dat, city, temp);
Console.WriteLine(output);
// The example displays output like the following:
//    At 1/17/2012 9:30:00 AM in Chicago, the temperature was -16 degrees.
open System

let dat = DateTime(2012, 1, 17, 9, 30, 0) 
let city = "Chicago"
let temp = -16
String.Format("At {0} in {1}, the temperature was {2} degrees.", dat, city, temp)
|> printfn "%s"
// The example displays output like the following:
//    At 1/17/2012 9:30:00 AM in Chicago, the temperature was -16 degrees.
Dim dat As Date = #1/17/2012 9:30AM#
Dim city As String = "Chicago"
Dim temp As Integer = -16
Dim output As String = String.Format("At {0} in {1}, the temperature was {2} degrees.",
                                   dat, city, temp)
Console.WriteLine(output)
' The example displays the following output:
'    At 1/17/2012 9:30:00 AM in Chicago, the temperature was -16 degrees.

Das Formatelement

Ein Formatelement weist die folgende Syntax auf:

{index[,alignment][:formatString]}

Klammern geben optionale Elemente an. Die öffnenden und schließenden geschweiften Klammern sind erforderlich. (Informationen zum Einschließen einer literalen öffnenden oder schließenden Klammer in die Formatzeichenfolge finden Sie unter Abschnitt "Klammern klammern " im Artikel "Zusammengesetzte Formatierung ".)

Ein Formatelement zum Formatieren eines Währungswerts kann z. B. wie folgt aussehen:

var value = String.Format("{0,-10:C}", 126347.89m);
Console.WriteLine(value);
open System

String.Format("{0,-10:C}", 126347.89m)         
|> printfn "%s"
String.Format("{0,-10:C}", 126347.89D)

Ein Formatelement weist die folgenden Elemente auf:

Index
Der nullbasierte Index des Arguments, dessen Zeichenfolgendarstellung an dieser Position in der Zeichenfolge enthalten sein soll. Wenn dieses Argument lautet null, wird an dieser Position in der Zeichenfolge eine leere Zeichenfolge eingeschlossen.

Ausrichtung
Optional. Eine signierte ganze Zahl, die die Gesamtlänge des Felds angibt, in das das Argument eingefügt wird und ob es rechtsbündig (eine positive ganze Zahl) oder linksbündig (eine negative ganze Zahl) ist. Wenn Sie die Ausrichtung weglassen, wird die Zeichenfolgendarstellung des entsprechenden Arguments in ein Feld ohne führende oder nachfolgende Leerzeichen eingefügt.

Wenn der Wert der Ausrichtung kleiner als die Länge des einzufügenden Arguments ist, wird die Ausrichtung ignoriert, und die Länge der Zeichenfolgendarstellung des Arguments wird als Feldbreite verwendet.

Formatstring
Optional. Eine Zeichenfolge, die das Format der Ergebniszeichenfolge des entsprechenden Arguments angibt. Wenn Sie formatString weglassen, wird die parameterlose ToString Methode des entsprechenden Arguments aufgerufen, um die Zeichenfolgendarstellung zu erzeugen. Wenn Sie formatString angeben, muss das Argument, auf das vom Formatelement verwiesen wird, die IFormattable Schnittstelle implementieren. Zu den Typen, die Formatzeichenfolgen unterstützen, gehören:

Beachten Sie jedoch, dass jeder benutzerdefinierte Typ die Implementierung eines vorhandenen Typs IFormattable implementieren IFormattable oder erweitern kann.

Im folgenden Beispiel werden die und formatString die alignment Argumente verwendet, um eine formatierte Ausgabe zu erzeugen.

// Create array of 5-tuples with population data for three U.S. cities, 1940-1950.
Tuple<string, DateTime, int, DateTime, int>[] cities = 
    { Tuple.Create("Los Angeles", new DateTime(1940, 1, 1), 1504277, 
                   new DateTime(1950, 1, 1), 1970358),
      Tuple.Create("New York", new DateTime(1940, 1, 1), 7454995, 
                   new DateTime(1950, 1, 1), 7891957),  
      Tuple.Create("Chicago", new DateTime(1940, 1, 1), 3396808, 
                   new DateTime(1950, 1, 1), 3620962),  
      Tuple.Create("Detroit", new DateTime(1940, 1, 1), 1623452, 
                   new DateTime(1950, 1, 1), 1849568) };

// Display header
var header = String.Format("{0,-12}{1,8}{2,12}{1,8}{2,12}{3,14}\n",
                              "City", "Year", "Population", "Change (%)");
Console.WriteLine(header);
foreach (var city in cities) {
   var output = String.Format("{0,-12}{1,8:yyyy}{2,12:N0}{3,8:yyyy}{4,12:N0}{5,14:P1}",
                          city.Item1, city.Item2, city.Item3, city.Item4, city.Item5,
                          (city.Item5 - city.Item3)/ (double)city.Item3);
   Console.WriteLine(output);
}
// The example displays the following output:
//    City            Year  Population    Year  Population    Change (%)
//  
//    Los Angeles     1940   1,504,277    1950   1,970,358        31.0 %
//    New York        1940   7,454,995    1950   7,891,957         5.9 %
//    Chicago         1940   3,396,808    1950   3,620,962         6.6 %
//    Detroit         1940   1,623,452    1950   1,849,568        13.9 %
// Create a list of 5-tuples with population data for three U.S. cities, 1940-1950.
let cities = 
    [ "Los Angeles", DateTime(1940, 1, 1), 1504277, DateTime(1950, 1, 1), 1970358
      "New York", DateTime(1940, 1, 1), 7454995, DateTime(1950, 1, 1), 7891957
      "Chicago", DateTime(1940, 1, 1), 3396808, DateTime(1950, 1, 1), 3620962
      "Detroit", DateTime(1940, 1, 1), 1623452, DateTime(1950, 1, 1), 1849568 ]

// Display header
String.Format("{0,-12}{1,8}{2,12}{1,8}{2,12}{3,14}\n", "City", "Year", "Population", "Change (%)")
|> printfn "%s"

for name, year1, pop1, year2, pop2 in cities do
    String.Format("{0,-12}{1,8:yyyy}{2,12:N0}{3,8:yyyy}{4,12:N0}{5,14:P1}",
                  name, year1, pop1, year2, pop2,
                  double (pop2 - pop1) / double pop1)
    |> printfn "%s"
// The example displays the following output:
//    City            Year  Population    Year  Population    Change (%)
//  
//    Los Angeles     1940   1,504,277    1950   1,970,358        31.0 %
//    New York        1940   7,454,995    1950   7,891,957         5.9 %
//    Chicago         1940   3,396,808    1950   3,620,962         6.6 %
//    Detroit         1940   1,623,452    1950   1,849,568        13.9 %
Module Example3
    Public Sub Main()
        ' Create array of 5-tuples with population data for three U.S. cities, 1940-1950.
        Dim cities() =
          {Tuple.Create("Los Angeles", #1/1/1940#, 1504277, #1/1/1950#, 1970358),
            Tuple.Create("New York", #1/1/1940#, 7454995, #1/1/1950#, 7891957),
            Tuple.Create("Chicago", #1/1/1940#, 3396808, #1/1/1950#, 3620962),
            Tuple.Create("Detroit", #1/1/1940#, 1623452, #1/1/1950#, 1849568)}

        ' Display header
        Dim header As String = String.Format("{0,-12}{1,8}{2,12}{1,8}{2,12}{3,14}",
                                           "City", "Year", "Population", "Change (%)")
        Console.WriteLine(header)
        Console.WriteLine()
        For Each city In cities
            Dim output = String.Format("{0,-12}{1,8:yyyy}{2,12:N0}{3,8:yyyy}{4,12:N0}{5,14:P1}",
                                city.Item1, city.Item2, city.Item3, city.Item4, city.Item5,
                                (city.Item5 - city.Item3) / city.Item3)
            Console.WriteLine(output)
        Next
    End Sub
End Module
' The example displays the following output:
'    City            Year  Population    Year  Population    Change (%)
'    
'    Los Angeles     1940   1,504,277    1950   1,970,358        31.0 %
'    New York        1940   7,454,995    1950   7,891,957         5.9 %
'    Chicago         1940   3,396,808    1950   3,620,962         6.6 %
'    Detroit         1940   1,623,452    1950   1,849,568        13.9 %

Formatieren von Argumenten

Formatelemente werden sequenziell vom Anfang der Zeichenfolge verarbeitet. Jedes Formatelement weist einen Index auf, der einem Objekt in der Argumentliste der Methode entspricht. Die Format Methode ruft das Argument ab und leitet die Zeichenfolgendarstellung wie folgt ab:

  • Wenn das Argument lautet null, wird die Methode in die Ergebniszeichenfolge eingefügt String.Empty . Sie müssen sich nicht mit der Behandlung von NullReferenceException Null-Argumenten befassen.

  • Wenn Sie die Format(IFormatProvider, String, Object[]) Überladung aufrufen und die provider Implementierung des IFormatProvider.GetFormat Objekts eine Nicht-NULL-Implementierung ICustomFormatter zurückgibt, wird das Argument an seine ICustomFormatter.Format(String, Object, IFormatProvider) Methode übergeben. Wenn das Formatelement ein formatString-Argument enthält, wird es als erstes Argument an die Methode übergeben. Wenn die ICustomFormatter Implementierung verfügbar ist und eine Zeichenfolge ohne Null erzeugt wird, wird diese Zeichenfolge als Zeichenfolgendarstellung des Arguments zurückgegeben. Andernfalls wird der nächste Schritt ausgeführt.

  • Wenn das Argument die IFormattable Schnittstelle implementiert, wird die IFormattable.ToString Implementierung aufgerufen.

  • Die parameterlose ToString Methode des Arguments, die entweder außer Kraft setzt oder von einer Basisklassenimplementierung erbt, wird aufgerufen.

Ein Beispiel, das Aufrufe der ICustomFormatter.Format Methode abfangen und ihnen ermöglicht, zu sehen, welche Informationen die Format Methode an eine Formatierungsmethode für jedes Formatelement in einer zusammengesetzten Formatzeichenfolge übergibt, finden Sie unter Beispiel: Ein Intercept Provider und ein römischer Zahlenformatierer.

Weitere Informationen finden Sie unter "Auftragsverarbeitung".

Formatieren von Elementen mit demselben Index

Die Format Methode löst eine FormatException Ausnahme aus, wenn der Index eines Indexelements größer oder gleich der Anzahl der Argumente in der Argumentliste ist. Kann jedoch mehr Formatelemente enthalten, format als Argumente vorhanden sind, solange mehrere Formatelemente denselben Index aufweisen. Im Aufruf der Format(String, Object) Methode im folgenden Beispiel weist die Argumentliste ein einzelnes Argument auf, aber die Formatzeichenfolge enthält zwei Formatelemente: eine zeigt den Dezimalwert einer Zahl an, und die andere zeigt ihren Hexadezimalwert an.

short[] values= { Int16.MinValue, -27, 0, 1042, Int16.MaxValue };
Console.WriteLine("{0,10}  {1,10}\n", "Decimal", "Hex");
foreach (short value in values)
{
   string formatString = String.Format("{0,10:G}: {0,10:X}", value);
   Console.WriteLine(formatString);
}   
// The example displays the following output:
//       Decimal         Hex
//    
//        -32768:       8000
//           -27:       FFE5
//             0:          0
//          1042:        412
//         32767:       7FFF
open System

let values= [| Int16.MinValue; -27s; 0s; 1042s; Int16.MaxValue |]
printfn "%10s  %10s\n" "Decimal" "Hex"
for value in values do
    String.Format("{0,10:G}: {0,10:X}", value)
    |> printfn "%s"
// The example displays the following output:
//       Decimal         Hex
//    
//        -32768:       8000
//           -27:       FFE5
//             0:          0
//          1042:        412
//         32767:       7FFF
Module Example1
    Public Sub Main()
        Dim values() As Short = {Int16.MinValue, -27, 0, 1042, Int16.MaxValue}
        Console.WriteLine("{0,10}  {1,10}", "Decimal", "Hex")
        Console.WriteLine()
        For Each value As Short In values
            Dim formatString As String = String.Format("{0,10:G}: {0,10:X}", value)
            Console.WriteLine(formatString)
        Next
    End Sub
End Module
' The example displays the following output:
'       Decimal         Hex
'    
'        -32768:       8000
'           -27:       FFE5
'             0:          0
'          1042:        412
'         32767:       7FFF

Format und Kultur

Im Allgemeinen werden Objekte in der Argumentliste mithilfe der Konventionen der aktuellen Kultur in ihre Zeichenfolgendarstellungen konvertiert, die von der CultureInfo.CurrentCulture Eigenschaft zurückgegeben werden. Sie können dieses Verhalten steuern, indem Sie eine der Überladungen aufrufen, die Format einen provider Parameter enthalten. Der provider Parameter ist eine IFormatProvider Implementierung, die benutzerdefinierte und kulturspezifische Formatierungsinformationen bereitstellt, die zum Moderieren des Formatierungsprozesses verwendet werden.

Die IFormatProvider Schnittstelle verfügt über ein einzelnes Element, GetFormatdas für die Rückgabe des Objekts verantwortlich ist, das Formatierungsinformationen bereitstellt. .NET verfügt über drei IFormatProvider Implementierungen, die kulturspezifische Formatierungen bereitstellen:

Benutzerdefinierte Formatierungsvorgänge

Sie können auch die Überladungen der Methode aufrufen, die Format über einen provider Parameter vom Typ IFormatProvider verfügen, um benutzerdefinierte Formatierungsvorgänge auszuführen. Sie können z. B. eine ganze Zahl als Identifikationsnummer oder als Telefonnummer formatieren. Zum Ausführen einer benutzerdefinierten Formatierung muss das provider Argument sowohl die Als ICustomFormatter auch die IFormatProvider Schnittstellen implementieren. Wenn die Format Methode als provider Argument eine ICustomFormatter Implementierung übergeben wird, ruft die Methode die Format Implementierung auf IFormatProvider.GetFormat und fordert ein Objekt vom Typ anICustomFormatter. Anschließend wird die Methode des zurückgegebenen ICustomFormatter Objekts Format aufgerufen, um jedes Formatelement in der an das Objekt übergebenen zusammengesetzten Zeichenfolge zu formatieren.

Weitere Informationen zum Bereitstellen von benutzerdefinierten Formatierungslösungen finden Sie unter How to: Define and Use Custom Numeric Format Providers and ICustomFormatter. Ein Beispiel, das ganze Zahlen in formatierte benutzerdefinierte Zahlen konvertiert, finden Sie unter Beispiel: Ein benutzerdefinierter Formatierungsvorgang. Ein Beispiel, das nicht signierte Bytes in römische Ziffern konvertiert, finden Sie unter Beispiel: Ein Intercept Provider und ein römischer Zahlenformatierer.

Beispiel: Ein benutzerdefinierter Formatierungsvorgang

In diesem Beispiel wird ein Formatanbieter definiert, der einen ganzzahligen Wert als Kundenkontonummer im Format x-xxxxx-xx formatiert.

using System;

public class TestFormatter
{
   public static void Main()
   {
      int acctNumber = 79203159;
      Console.WriteLine(String.Format(new CustomerFormatter(), "{0}", acctNumber));
      Console.WriteLine(String.Format(new CustomerFormatter(), "{0:G}", acctNumber));
      Console.WriteLine(String.Format(new CustomerFormatter(), "{0:S}", acctNumber));
      Console.WriteLine(String.Format(new CustomerFormatter(), "{0:P}", acctNumber));
      try {
         Console.WriteLine(String.Format(new CustomerFormatter(), "{0:X}", acctNumber));
      }
      catch (FormatException e) {
         Console.WriteLine(e.Message);
      }
   }
}

public class CustomerFormatter : 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 (! this.Equals(formatProvider))
      {
         return null;
      }
      else
      {
         if (String.IsNullOrEmpty(format)) 
            format = "G";
         
         string customerString = arg.ToString();
         if (customerString.Length < 8)
            customerString = customerString.PadLeft(8, '0');
         
         format = format.ToUpper();
         switch (format)
         {
            case "G":
               return customerString.Substring(0, 1) + "-" +
                                     customerString.Substring(1, 5) + "-" +
                                     customerString.Substring(6);
            case "S":                          
               return customerString.Substring(0, 1) + "/" +
                                     customerString.Substring(1, 5) + "/" +
                                     customerString.Substring(6);
            case "P":                          
               return customerString.Substring(0, 1) + "." +
                                     customerString.Substring(1, 5) + "." +
                                     customerString.Substring(6);
            default:
               throw new FormatException( 
                         String.Format("The '{0}' format specifier is not supported.", format));
         }
      }   
   }
}
// The example displays the following output:
//       7-92031-59
//       7-92031-59
//       7/92031/59
//       7.92031.59
//       The 'X' format specifier is not supported.
open System

type CustomerFormatter() = 
    interface IFormatProvider with
        member this.GetFormat(formatType) =
            if formatType = typeof<ICustomFormatter> then
                this
            else
                null

    interface ICustomFormatter with
        member this.Format(format, arg, formatProvider: IFormatProvider) = 
            if this.Equals formatProvider |> not then
                null
            else
                let format = 
                    if String.IsNullOrEmpty format then "G"
                    else format.ToUpper()
                
                let customerString = 
                    let s = string arg
                    if s.Length < 8 then
                        s.PadLeft(8, '0')
                    else s
                
                match format with
                | "G" ->
                    customerString.Substring(0, 1) + "-" +
                        customerString.Substring(1, 5) + "-" +
                        customerString.Substring 6
                | "S" ->                          
                    customerString.Substring(0, 1) + "/" +
                        customerString.Substring(1, 5) + "/" +
                        customerString.Substring 6
                | "P" ->                          
                    customerString.Substring(0, 1) + "." +
                        customerString.Substring(1, 5) + "." +
                        customerString.Substring 6
                | _ ->
                    raise (FormatException $"The '{format}' format specifier is not supported.")

let acctNumber = 79203159
String.Format(CustomerFormatter(), "{0}", acctNumber)
|> printfn "%s"
String.Format(CustomerFormatter(), "{0:G}", acctNumber)
|> printfn "%s"
String.Format(CustomerFormatter(), "{0:S}", acctNumber)
|> printfn "%s"
String.Format(CustomerFormatter(), "{0:P}", acctNumber)
|> printfn "%s"
try
    String.Format(CustomerFormatter(), "{0:X}", acctNumber)
    |> printfn "%s"
with :? FormatException as e ->
    printfn $"{e.Message}"

// The example displays the following output:
//       7-92031-59
//       7-92031-59
//       7/92031/59
//       7.92031.59
//       The 'X' format specifier is not supported.
Module TestFormatter
   Public Sub Main()
      Dim acctNumber As Integer = 79203159
      Console.WriteLine(String.Format(New CustomerFormatter, "{0}", acctNumber))
      Console.WriteLine(String.Format(New CustomerFormatter, "{0:G}", acctNumber))
      Console.WriteLine(String.Format(New CustomerFormatter, "{0:S}", acctNumber))
      Console.WriteLine(String.Format(New CustomerFormatter, "{0:P}", acctNumber))
      Try
         Console.WriteLine(String.Format(New CustomerFormatter, "{0:X}", acctNumber))
      Catch e As FormatException
         Console.WriteLine(e.Message)
      End Try   
   End Sub
End Module

Public Class CustomerFormatter : Implements IFormatProvider, ICustomFormatter
   Public Function GetFormat(type As Type) As Object  _
                   Implements IFormatProvider.GetFormat
      If type 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 Me.Equals(formatProvider) Then
         Return Nothing
      Else
         If String.IsNullOrEmpty(fmt) Then fmt = "G"
         
         Dim customerString As String = arg.ToString()
         if customerString.Length < 8 Then _
            customerString = customerString.PadLeft(8, "0"c)
         
         Select Case fmt
            Case "G"
               Return customerString.Substring(0, 1) & "-" & _
                                     customerString.Substring(1, 5) & "-" & _
                                     customerString.Substring(6)
            Case "S"                         
               Return customerString.Substring(0, 1) & "/" & _
                                     customerString.Substring(1, 5) & "/" & _
                                     customerString.Substring(6)
            Case "P"
               Return customerString.Substring(0, 1) & "." & _
                                     customerString.Substring(1, 5) & "." & _
                                     customerString.Substring(6)
            Case Else
               Throw New FormatException( _
                         String.Format("The '{0}' format specifier is not supported.", fmt))
         End Select                                                     
      End If   
   End Function
End Class
' The example displays the following output:
'       7-92031-59
'       7-92031-59
'       7/92031/59
'       7.92031.59
'       The 'X' format specifier is not supported.

Beispiel: Ein Schnittpunktanbieter und ein römischer Zahlenformatierer

In diesem Beispiel wird ein benutzerdefinierter Formatanbieter definiert, der die ICustomFormatter beiden IFormatProvider Folgenden implementiert:

  • Es zeigt die Parameter an, die an die ICustomFormatter.Format Implementierung übergeben werden. Auf diese Weise können wir sehen, welche Parameter die Format(IFormatProvider, String, Object[]) Methode an die benutzerdefinierte Formatierungsimplementierung für jedes Objekt übergibt, das sie formatieren möchte. Dies kann hilfreich sein, wenn Sie Ihre Anwendung debuggen.

  • Wenn das zu formatierende Objekt ein nicht signierter Bytewert ist, der mithilfe der Standardformatzeichenfolge "R" formatiert werden soll, formatiert der benutzerdefinierte Formatierer den numerischen Wert als römische Zahl.

using System;
using System.Globalization;

public class InterceptProvider : IFormatProvider, ICustomFormatter
{
   public object GetFormat(Type formatType)
   {
      if (formatType == typeof(ICustomFormatter))
         return this;
      else
         return null;
   }
   
   public string Format(String format, Object obj, IFormatProvider provider) 
   {
      // Display information about method call.
      string formatString = format ?? "<null>";
      Console.WriteLine("Provider: {0}, Object: {1}, Format String: {2}",
                        provider.GetType().Name, obj ?? "<null>", formatString);
                        
      if (obj == null) return String.Empty;
            
      // If this is a byte and the "R" format string, format it with Roman numerals.
      if (obj is Byte && formatString.ToUpper().Equals("R")) {
         Byte value = (Byte) obj;
         int remainder;
         int result;
         String returnString = String.Empty;

         // Get the hundreds digit(s)
         result = Math.DivRem(value, 100, out remainder);
         if (result > 0)  
            returnString = new String('C', result);
         value = (Byte) remainder;
         // Get the 50s digit
         result = Math.DivRem(value, 50, out remainder);
         if (result == 1)
            returnString += "L";
         value = (Byte) remainder;
         // Get the tens digit.
         result = Math.DivRem(value, 10, out remainder);
         if (result > 0)
            returnString += new String('X', result);
         value = (Byte) remainder; 
         // Get the fives digit.
         result = Math.DivRem(value, 5, out remainder);
         if (result > 0)
            returnString += "V";
         value = (Byte) remainder;
         // Add the ones digit.
         if (remainder > 0) 
            returnString += new String('I', remainder);
         
         // Check whether we have too many X characters.
         int pos = returnString.IndexOf("XXXX");
         if (pos >= 0) {
            int xPos = returnString.IndexOf("L"); 
            if (xPos >= 0 & xPos == pos - 1)
               returnString = returnString.Replace("LXXXX", "XC");
            else
               returnString = returnString.Replace("XXXX", "XL");   
         }
         // Check whether we have too many I characters
         pos = returnString.IndexOf("IIII");
         if (pos >= 0)
            if (returnString.IndexOf("V") >= 0)
               returnString = returnString.Replace("VIIII", "IX");
            else
               returnString = returnString.Replace("IIII", "IV");    

         return returnString; 
      }   

      // Use default for all other formatting.
      if (obj is IFormattable)
         return ((IFormattable) obj).ToString(format, CultureInfo.CurrentCulture);
      else
         return obj.ToString();
   }
}

public class Example
{
   public static void Main()
   {
      int n = 10;
      double value = 16.935;
      DateTime day = DateTime.Now;
      InterceptProvider provider = new InterceptProvider();
      Console.WriteLine(String.Format(provider, "{0:N0}: {1:C2} on {2:d}\n", n, value, day));
      Console.WriteLine(String.Format(provider, "{0}: {1:F}\n", "Today: ", 
                                      (DayOfWeek) DateTime.Now.DayOfWeek));
      Console.WriteLine(String.Format(provider, "{0:X}, {1}, {2}\n", 
                                      (Byte) 2, (Byte) 12, (Byte) 199));
      Console.WriteLine(String.Format(provider, "{0:R}, {1:R}, {2:R}\n", 
                                      (Byte) 2, (Byte) 12, (Byte) 199));
   }
}
// The example displays the following output:
//    Provider: InterceptProvider, Object: 10, Format String: N0
//    Provider: InterceptProvider, Object: 16.935, Format String: C2
//    Provider: InterceptProvider, Object: 1/31/2013 6:10:28 PM, Format String: d
//    10: $16.94 on 1/31/2013
//    
//    Provider: InterceptProvider, Object: Today: , Format String: <null>
//    Provider: InterceptProvider, Object: Thursday, Format String: F
//    Today: : Thursday
//    
//    Provider: InterceptProvider, Object: 2, Format String: X
//    Provider: InterceptProvider, Object: 12, Format String: <null>
//    Provider: InterceptProvider, Object: 199, Format String: <null>
//    2, 12, 199
//    
//    Provider: InterceptProvider, Object: 2, Format String: R
//    Provider: InterceptProvider, Object: 12, Format String: R
//    Provider: InterceptProvider, Object: 199, Format String: R
//    II, XII, CXCIX
open System
open System.Globalization

type InterceptProvider() =
    interface IFormatProvider with
        member this.GetFormat(formatType) =
            if formatType = typeof<ICustomFormatter> then
                this
            else
                null
    interface ICustomFormatter with
        member _.Format(format, obj, provider: IFormatProvider) = 
            // Display information about method call.
            let formatString =
                if format = null then "<null>" else format
            printfn $"Provider: {provider.GetType().Name}, Object: %A{obj}, Format String: %s{formatString}"
                                
            if obj = null then
                String.Empty
            else
                // If this is a byte and the "R" format string, format it with Roman numerals.
                match obj with
                | :? byte as value when formatString.ToUpper().Equals "R" -> 
                    let mutable returnString = String.Empty

                    // Get the hundreds digit(s)
                    let struct (result, remainder) = Math.DivRem(value, 100uy)
                    if result > 0uy then
                        returnString <- String('C', int result)
                    let value = byte remainder
                    // Get the 50s digit
                    let struct (result, remainder) = Math.DivRem(value, 50uy)
                    if result = 1uy then
                        returnString <- returnString + "L"
                    let value = byte remainder
                    // Get the tens digit.
                    let struct (result, remainder) = Math.DivRem(value, 10uy)
                    if result > 0uy then
                        returnString <- returnString + String('X', int result)
                    let value = byte remainder 
                    // Get the fives digit.
                    let struct (result, remainder) = Math.DivRem(value, 5uy)
                    if result > 0uy then
                        returnString <- returnString + "V"
                    let value = byte remainder
                    // Add the ones digit.
                    if remainder > 0uy then 
                        returnString <- returnString + String('I', int remainder)
                    
                    // Check whether we have too many X characters.
                    let pos = returnString.IndexOf "XXXX"
                    if pos >= 0 then
                        let xPos = returnString.IndexOf "L" 
                        returnString <-
                            if xPos >= 0 && xPos = pos - 1 then
                                returnString.Replace("LXXXX", "XC")
                            else
                                returnString.Replace("XXXX", "XL")   
                    // Check whether we have too many I characters
                    let pos = returnString.IndexOf "IIII"
                    if pos >= 0 then
                        returnString <-
                            if returnString.IndexOf "V" >= 0 then
                                returnString.Replace("VIIII", "IX")
                            else
                                returnString.Replace("IIII", "IV")    
                    returnString 

                // Use default for all other formatting.
                | :? IFormattable as x ->
                    x.ToString(format, CultureInfo.CurrentCulture)
                | _ ->
                    string obj

let n = 10
let value = 16.935
let day = DateTime.Now
let provider = InterceptProvider()
String.Format(provider, "{0:N0}: {1:C2} on {2:d}\n", n, value, day)
|> printfn "%s"
String.Format(provider, "{0}: {1:F}\n", "Today: ", DateTime.Now.DayOfWeek)
|> printfn "%s"
String.Format(provider, "{0:X}, {1}, {2}\n", 2uy, 12uy, 199uy)
|> printfn "%s"
String.Format(provider, "{0:R}, {1:R}, {2:R}\n", 2uy, 12uy, 199uy)
|> printfn "%s"
// The example displays the following output:
//    Provider: InterceptProvider, Object: 10, Format String: N0
//    Provider: InterceptProvider, Object: 16.935, Format String: C2
//    Provider: InterceptProvider, Object: 1/31/2013 6:10:28 PM, Format String: d
//    10: $16.94 on 1/31/2013
//    
//    Provider: InterceptProvider, Object: Today: , Format String: <null>
//    Provider: InterceptProvider, Object: Thursday, Format String: F
//    Today: : Thursday
//    
//    Provider: InterceptProvider, Object: 2, Format String: X
//    Provider: InterceptProvider, Object: 12, Format String: <null>
//    Provider: InterceptProvider, Object: 199, Format String: <null>
//    2, 12, 199
//    
//    Provider: InterceptProvider, Object: 2, Format String: R
//    Provider: InterceptProvider, Object: 12, Format String: R
//    Provider: InterceptProvider, Object: 199, Format String: R
//    II, XII, CXCIX
Imports System.Globalization

Public Class InterceptProvider : 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, obj As Object, provider As IFormatProvider) As String _
         Implements ICustomFormatter.Format

      Dim formatString As String = If(fmt IsNot Nothing, fmt, "<null>")
      Console.WriteLine("Provider: {0}, Object: {1}, Format String: {2}",
                        provider, If(obj IsNot Nothing, obj, "<null>"), formatString)

      If obj Is Nothing Then Return String.Empty
            
      ' If this is a byte and the "R" format string, format it with Roman numerals.
      If TypeOf(obj) Is Byte AndAlso formatString.ToUpper.Equals("R") Then
         Dim value As Byte = CByte(obj)
         Dim remainder As Integer
         Dim result As Integer
         Dim returnString As String = String.Empty

         ' Get the hundreds digit(s)
         result = Math.DivRem(value, 100, remainder)
         If result > 0 Then returnString = New String("C"c, result)
         value = CByte(remainder)
         ' Get the 50s digit
         result = Math.DivRem(value, 50, remainder)
         If result = 1 Then returnString += "L"
         value = CByte(remainder)
         ' Get the tens digit.
         result = Math.DivRem(value, 10, remainder)
         If result > 0 Then returnString += New String("X"c, result)
         value = CByte(remainder) 
         ' Get the fives digit.
         result = Math.DivRem(value, 5, remainder)
         If result > 0 Then returnString += "V"
         value = CByte(remainder)
         ' Add the ones digit.
         If remainder > 0 Then returnString += New String("I"c, remainder)
         
         ' Check whether we have too many X characters.
         Dim pos As Integer = returnString.IndexOf("XXXX")
         If pos >= 0 Then
            Dim xPos As Integer = returnString.IndexOf("L") 
            If xPos >= 0 And xPos = pos - 1 Then
               returnString = returnString.Replace("LXXXX", "XC")
            Else
               returnString = returnString.Replace("XXXX", "XL")   
            End If         
         End If
         ' Check whether we have too many I characters
         pos = returnString.IndexOf("IIII")
         If pos >= 0 Then
            If returnString.IndexOf("V") >= 0 Then
               returnString = returnString.Replace("VIIII", "IX")
            Else
               returnString = returnString.Replace("IIII", "IV")    
            End If
         End If
         Return returnString 
      End If   

      ' Use default for all other formatting.
      If obj Is GetType(IFormattable)
         Return CType(obj, IFormattable).ToString(fmt, CultureInfo.CurrentCulture)
      Else
         Return obj.ToString()
      End If
   End Function
End Class

Module Example
   Public Sub Main()
      Dim n As Integer = 10
      Dim value As Double = 16.935
      Dim day As DateTime = Date.Now
      Dim provider As New InterceptProvider()
      Console.WriteLine(String.Format(provider, "{0:N0}: {1:C2} on {2:d}", n, value, day))
      Console.WriteLine()
      Console.WriteLine(String.Format(provider, "{0}: {1:F}", "Today", 
                                      CType(Date.Now.DayOfWeek, DayOfWeek)))
      Console.WriteLine()
      Console.WriteLine(String.Format(provider, "{0:X}, {1}, {2}\n", 
                                      CByte(2), CByte(12), CByte(199)))
      Console.WriteLine()
      Console.WriteLine(String.Format(provider, "{0:R}, {1:R}, {2:R}", 
                                      CByte(2), CByte(12), CByte(199)))
   End Sub
End Module
' The example displays the following output:
'    Provider: InterceptProvider, Object: 10, Format String: N0
'    Provider: InterceptProvider, Object: 16.935, Format String: C2
'    Provider: InterceptProvider, Object: 1/31/2013 6:10:28 PM, Format String: d
'    10: $16.94 on 1/31/2013
'    
'    Provider: InterceptProvider, Object: Today: , Format String: <null>
'    Provider: InterceptProvider, Object: Thursday, Format String: F
'    Today: : Thursday
'    
'    Provider: InterceptProvider, Object: 2, Format String: X
'    Provider: InterceptProvider, Object: 12, Format String: <null>
'    Provider: InterceptProvider, Object: 199, Format String: <null>
'    2, 12, 199
'    
'    Provider: InterceptProvider, Object: 2, Format String: R
'    Provider: InterceptProvider, Object: 12, Format String: R
'    Provider: InterceptProvider, Object: 199, Format String: R
'    II, XII, CXCIX

Häufig gestellte Fragen

Warum empfehlen Sie die Zeichenfolgeninterpolation über Aufrufe der String.Format Methode?

Die Zeichenfolgeninterpolation lautet:

  • Flexibler. Sie kann in einer beliebigen Zeichenfolge verwendet werden, ohne dass ein Aufruf einer Methode erforderlich ist, die zusammengesetzte Formatierung unterstützt. Andernfalls müssen Sie die Format Methode oder eine andere Methode aufrufen, die zusammengesetzte Formatierung unterstützt, z Console.WriteLine . B. oder StringBuilder.AppendFormat.

  • Besser lesbar. Da der in eine Zeichenfolge einzufügende Ausdruck im interpolierten Ausdruck und nicht in einer Argumentliste angezeigt wird, sind interpolierte Zeichenfolgen wesentlich einfacher zu codieren und zu lesen. Aufgrund ihrer besseren Lesbarkeit können interpolierte Zeichenfolgen nicht nur Aufrufe von Zusammengesetztformatmethoden ersetzen, sondern auch in Zeichenfolgenverkettungsvorgängen verwendet werden, um präziseren, klareren Code zu erzeugen.

Ein Vergleich der folgenden beiden Codebeispiele veranschaulicht die Überlegenheit interpolierter Zeichenfolgen gegenüber Zeichenfolgenverkettung und Aufrufen zusammengesetzter Formatierungsmethoden. Die Verwendung mehrerer Zeichenfolgenverkettungsvorgänge im folgenden Beispiel erzeugt ausführlichen und schwer zu lesenden Code.

string[] names = { "Balto", "Vanya", "Dakota", "Samuel", "Koani", "Yiska", "Yuma" };
string output = names[0] + ", " + names[1] + ", " + names[2] + ", " +
                names[3] + ", " + names[4] + ", " + names[5] + ", " +
                names[6];

output += "\n";
var date = DateTime.Now;
output += String.Format("It is {0:t} on {0:d}. The day of the week is {1}.",
                        date, date.DayOfWeek);
Console.WriteLine(output);
// The example displays the following output:
//     Balto, Vanya, Dakota, Samuel, Koani, Yiska, Yuma
//     It is 10:29 AM on 1/8/2018. The day of the week is Monday.
open System

let names = [| "Balto"; "Vanya"; "Dakota"; "Samuel"; "Koani"; "Yiska"; "Yuma" |]
let output = 
    names[0] + ", " + names[1] + ", " + names[2] + ", " + 
    names[3] + ", " + names[4] + ", " + names[5] + ", " + 
    names[6] + "\n"

let date = DateTime.Now
output + String.Format("It is {0:t} on {0:d}. The day of the week is {1}.", date, date.DayOfWeek)
|> printfn "%s"
// The example displays the following output:
//     Balto, Vanya, Dakota, Samuel, Koani, Yiska, Yuma
//     It is 10:29 AM on 1/8/2018. The day of the week is Monday.

Module Example12
    Public Sub Main()
        Dim names = {"Balto", "Vanya", "Dakota", "Samuel", "Koani", "Yiska", "Yuma"}
        Dim output = names(0) + ", " + names(1) + ", " + names(2) + ", " +
                   names(3) + ", " + names(4) + ", " + names(5) + ", " +
                   names(6)

        output += vbCrLf
        Dim dat = DateTime.Now
        output += String.Format("It is {0:t} on {0:d}. The day of the week is {1}.",
                              dat, dat.DayOfWeek)
        Console.WriteLine(output)
    End Sub
End Module
' The example displays the following output:
'     Balto, Vanya, Dakota, Samuel, Koani, Yiska, Yuma
'     It is 10:29 AM on 1/8/2018. The day of the week is Monday.

Im Gegensatz dazu erzeugt die Verwendung interpolierter Zeichenfolgen im folgenden Beispiel viel klareren, präziseren Code als die Zeichenfolgenverkettungsanweisung und den Aufruf der Format Methode im vorherigen Beispiel.

string[] names = { "Balto", "Vanya", "Dakota", "Samuel", "Koani", "Yiska", "Yuma" };
string output = $"{names[0]}, {names[1]}, {names[2]}, {names[3]}, {names[4]}, " +
                $"{names[5]}, {names[6]}";

var date = DateTime.Now;
output += $"\nIt is {date:t} on {date:d}. The day of the week is {date.DayOfWeek}.";
Console.WriteLine(output);
// The example displays the following output:
//     Balto, Vanya, Dakota, Samuel, Koani, Yiska, Yuma
//     It is 10:29 AM on 1/8/2018. The day of the week is Monday.
open System

let names = [| "Balto"; "Vanya"; "Dakota"; "Samuel"; "Koani"; "Yiska"; "Yuma" |]
let output = $"{names[0]}, {names[1]}, {names[2]}, {names[3]}, {names[4]}, {names[5]}, {names[6]}"  

let date = DateTime.Now
output + $"\nIt is {date:t} on {date:d}. The day of the week is {date.DayOfWeek}."
|> printfn "%s" 
// The example displays the following output:
//     Balto, Vanya, Dakota, Samuel, Koani, Yiska, Yuma
//     It is 10:29 AM on 1/8/2018. The day of the week is Monday.

Module Example13
    Public Sub Main()
        Dim names = {"Balto", "Vanya", "Dakota", "Samuel", "Koani", "Yiska", "Yuma"}
        Dim output = $"{names(0)}, {names(1)}, {names(2)}, {names(3)}, {names(4)}, " +
                   $"{names(5)}, {names(6)}"

        Dim dat = DateTime.Now
        output += $"{vbCrLf}It is {dat:t} on {dat:d}. The day of the week is {dat.DayOfWeek}."
        Console.WriteLine(output)
    End Sub
End Module
' The example displays the following output:
'     Balto, Vanya, Dakota, Samuel, Koani, Yiska, Yuma
'     It is 10:29 AM on 1/8/2018. The day of the week is Monday.

Wo finde ich die vordefinierten Formatzeichenfolgen?

Gewusst wie die Ausrichtung der Ergebniszeichenfolgen steuern, die Formatelemente ersetzen?

Die allgemeine Syntax eines Formatelements lautet:

{index[,alignment][: formatString]}

Dabei handelt es sich bei der Ausrichtung um eine signierte ganze Zahl, die die Feldbreite definiert. Wenn dieser Wert negativ ist, wird text im Feld linksbündig ausgerichtet. Wenn es positiv ist, wird Text rechtsbündig ausgerichtet.

Gewusst wie die Anzahl der Ziffern nach dem Dezimaltrennzeichen steuern?

Alle standardmäßigen numerischen Formatzeichenfolgen mit Ausnahme von "D" (nur für ganze Zahlen verwendet), "G", "R" und "X" ermöglichen einen Genauigkeitsbezeichner, der die Anzahl der Dezimalziffern in der Ergebniszeichenfolge definiert. Im folgenden Beispiel werden standardmäßige numerische Formatzeichenfolgen verwendet, um die Anzahl der Dezimalziffern in der Ergebniszeichenfolge zu steuern.

object[] values = { 1603, 1794.68235, 15436.14 };
string result;
foreach (var value in values)
{
    result = String.Format("{0,12:C2}   {0,12:E3}   {0,12:F4}   {0,12:N3}  {1,12:P2}\n",
                           Convert.ToDouble(value), Convert.ToDouble(value) / 10000);
    Console.WriteLine(result);
}
// The example displays output like the following:
//       $1,603.00     1.603E+003      1603.0000      1,603.000       16.03 %
//    
//       $1,794.68     1.795E+003      1794.6824      1,794.682       17.95 %
//    
//      $15,436.14     1.544E+004     15436.1400     15,436.140      154.36 %
open System

let values: obj list = [ 1603, 1794.68235, 15436.14 ]
for value in values do
   String.Format("{0,12:C2}   {0,12:E3}   {0,12:F4}   {0,12:N3}  {1,12:P2}\n", Convert.ToDouble(value), Convert.ToDouble(value) / 10000.)
   |> printfn "%s"
// The example displays output like the following:
//       $1,603.00     1.603E+003      1603.0000      1,603.000       16.03 %
//    
//       $1,794.68     1.795E+003      1794.6824      1,794.682       17.95 %
//    
//      $15,436.14     1.544E+004     15436.1400     15,436.140      154.36 %
Module Example7
    Public Sub Main()
        Dim values() As Object = {1603, 1794.68235, 15436.14}
        Dim result As String
        For Each value In values
            result = String.Format("{0,12:C2}   {0,12:E3}   {0,12:F4}   {0,12:N3}  {1,12:P2}",
                                value, CDbl(value) / 10000)
            Console.WriteLine(result)
            Console.WriteLine()
        Next
    End Sub
End Module
' The example displays the following output:
'       $1,603.00     1.603E+003      1603.0000      1,603.000       16.03 %
'    
'       $1,794.68     1.795E+003      1794.6824      1,794.682       17.95 %
'    
'      $15,436.14     1.544E+004     15436.1400     15,436.140      154.36 %

Wenn Sie eine benutzerdefinierte zahlenformatige Zeichenfolge verwenden, verwenden Sie den Formatbezeichner "0", um die Anzahl der Dezimalstellen in der Ergebniszeichenfolge zu steuern, wie im folgenden Beispiel gezeigt.

decimal value = 16309.5436m;
string result = String.Format("{0,12:#.00000} {0,12:0,000.00} {0,12:000.00#}",
                              value);
Console.WriteLine(result);
// The example displays the following output:
//        16309.54360    16,309.54    16309.544
let value = 16309.5436m
String.Format("{0,12:#.00000} {0,12:0,000.00} {0,12:000.00#}", value)
|> printfn "%s"
// The example displays the following output:
//        16309.54360    16,309.54    16309.544
Module Example8
    Public Sub Main()
        Dim value As Decimal = 16309.5436D
        Dim result As String = String.Format("{0,12:#.00000} {0,12:0,000.00} {0,12:000.00#}",
                                           value)
        Console.WriteLine(result)
    End Sub
End Module
' The example displays the following output:
'    16309.54360    16,309.54    16309.544

Gewusst wie die Anzahl der integralen Ziffern steuern?

Formatierungsvorgänge zeigen standardmäßig nur Nicht-Null-Integralziffern an. Wenn Sie ganze Zahlen formatieren, können Sie einen Genauigkeitsbezeichner mit den Standardformatzeichenfolgen "D" und "X" verwenden, um die Anzahl der Ziffern zu steuern.

int value = 1326;
string result = String.Format("{0,10:D6} {0,10:X8}", value);
Console.WriteLine(result);
// The example displays the following output:
//     001326   0000052E
open System

let value = 1326
String.Format("{0,10:D6} {0,10:X8}", value)
|> printfn "%s"
// The example displays the following output:
//     001326   0000052E
Module Example10
    Public Sub Main()
        Dim value As Integer = 1326
        Dim result As String = String.Format("{0,10:D6} {0,10:X8}", value)
        Console.WriteLine(result)
    End Sub
End Module
' The example displays the following output:
'       001326   0000052E

Sie können eine ganzzahlige oder Gleitkommazahl mit führenden Nullen auffüllen, um eine Ergebniszeichenfolge mit einer angegebenen Anzahl integraler Ziffern zu erzeugen, indem Sie den benutzerdefinierten benutzerdefinierten Numerischen Formatbezeichner "0" verwenden, wie im folgenden Beispiel gezeigt.

int value = 16342;
string result = String.Format("{0,18:00000000} {0,18:00000000.000} {0,18:000,0000,000.0}",
                              value);
Console.WriteLine(result);
// The example displays the following output:
//           00016342       00016342.000    0,000,016,342.0
open System

let value = 16342
String.Format("{0,18:00000000} {0,18:00000000.000} {0,18:000,0000,000.0}", value)
|> printfn "%s"
// The example displays the following output:
//           00016342       00016342.000    0,000,016,342.0
Module Example9
    Public Sub Main()
        Dim value As Integer = 16342
        Dim result As String = String.Format("{0,18:00000000} {0,18:00000000.000} {0,18:000,0000,000.0}",
                                           value)
        Console.WriteLine(result)
    End Sub
End Module
' The example displays the following output:
'           00016342       00016342.000    0,000,016,342.0

Wie viele Elemente kann ich in die Formatliste aufnehmen?

Es gibt keine praktische Grenze. Der zweite Parameter der Format(IFormatProvider, String, Object[]) Methode wird mit dem ParamArrayAttribute Attribut markiert, mit dem Sie entweder eine durch Trennzeichen getrennte Liste oder ein Objektarray als Formatliste einschließen können.

Gewusst wie literale geschweifte Klammern ("{" und "}") in die Ergebniszeichenfolge einschließen?

Wie können Sie beispielsweise verhindern, dass der folgende Methodenaufruf eine FormatException Ausnahme auslöst?

result = String.Format("The text has {0} '{' characters and {1} '}' characters.",
                       nOpen, nClose);
let result = 
    String.Format("The text has {0} '{' characters and {1} '}' characters.", nOpen, nClose)
result = String.Format("The text has {0} '{' characters and {1} '}' characters.",
                 nOpen, nClose)

Eine einzelne öffnende oder schließende geschweifte Klammer wird immer als Anfang oder Ende eines Formatelements interpretiert. Um buchstäblich interpretiert zu werden, muss es entweicht werden. Sie escapen einer geschweiften Klammer, indem Sie wie im folgenden Methodenaufruf eine weitere geschweifte Klammer ("{" und "}}") anstelle von "{" und "}}" hinzufügen:

string result;
int nOpen = 1;
int nClose = 2;
result = String.Format("The text has {0} '{{' characters and {1} '}}' characters.",
                       nOpen, nClose);
Console.WriteLine(result);
let result =
    String.Format("The text has {0} '{{' characters and {1} '}}' characters.", nOpen, nClose)
result = String.Format("The text has {0} '{{' characters and {1} '}}' characters.",
                 nOpen, nClose)

Selbst escaped geschweifte Klammern werden jedoch leicht falsch interpretiert. Es wird empfohlen, geschweifte Klammern in die Formatliste einzuschließen und Formatelemente zum Einfügen in die Ergebniszeichenfolge zu verwenden, wie im folgenden Beispiel gezeigt.

string result;
int nOpen = 1;
int nClose = 2;
result = String.Format("The text has {0} '{1}' characters and {2} '{3}' characters.",
                       nOpen, "{", nClose, "}");
Console.WriteLine(result);
let result =
    String.Format("The text has {0} '{1}' characters and {2} '{3}' characters.", nOpen, "{", nClose, "}")
result = String.Format("The text has {0} '{1}' characters and {2} '{3}' characters.",
                 nOpen, "{", nClose, "}")

Warum löst mein Aufruf der String.Format-Methode eine FormatException aus?

Die häufigste Ursache für die Ausnahme ist, dass der Index eines Formatelements nicht einem Objekt in der Formatliste entspricht. In der Regel bedeutet dies, dass Sie die Indizes von Formatelementen falsch nummeriert haben oder vergessen haben, ein Objekt in die Formatliste einzuschließen. Wenn Sie versuchen, ein nicht gezeicheniertes links- oder rechtes geschweiftes Klammerzeichen einzuschließen, wird auch ein FormatException. Gelegentlich ist die Ausnahme das Ergebnis eines Tippfehlers; Ein typischer Fehler ist beispielsweise, "[" (die linke Klammer) anstelle von "{" (die linke geschweifte Klammer) falsch einzuschreiten.

Wenn die Format(System.IFormatProvider,System.String,System.Object[])-Methode Parameterarrays unterstützt, warum löst mein Code beim Verwenden eines Arrays eine Ausnahme aus?

Der folgende Code löst beispielsweise eine FormatException Ausnahme aus:

Random rnd = new Random();
int[] numbers = new int[4];
int total = 0;
for (int ctr = 0; ctr <= 2; ctr++)
{
    int number = rnd.Next(1001);
    numbers[ctr] = number;
    total += number;
}
numbers[3] = total;
Console.WriteLine("{0} + {1} + {2} = {3}", numbers);
open System

let rnd = Random()
let mutable total = 0
let numbers = Array.zeroCreate<int> 4
for i = 0 to 2 do
   let number = rnd.Next 1001
   numbers[i] <- number
   total <- total + number
numbers[3] <- total
Console.WriteLine("{0} + {1} + {2} = {3}", numbers)
Imports System.Collections.Generic

Module Example5
    Public Sub Main()
        Dim rnd As New Random()
        Dim numbers(3) As Integer
        Dim total As Integer = 0
        For ctr = 0 To 2
            Dim number As Integer = rnd.Next(1001)
            numbers(ctr) = number
            total += number
        Next
        numbers(3) = total
        Console.WriteLine("{0} + {1} + {2} = {3}", numbers)
    End Sub
End Module

Dies ist ein Problem mit der Compilerüberladungsauflösung. Da der Compiler kein Array mit ganzen Zahlen in ein Objektarray konvertieren kann, behandelt er das ganzzahlige Array als einzelnes Argument, sodass die Format(String, Object) Methode aufgerufen wird. Die Ausnahme wird ausgelöst, da es vier Formatelemente, aber nur ein einzelnes Element in der Formatliste gibt.

Da weder Visual Basic noch C# ein ganzzahliges Array in ein Objektarray konvertieren kann, müssen Sie die Konvertierung selbst ausführen, bevor Sie die Format(String, Object[]) Methode aufrufen. Der folgende Code zeigt ein Implementierungsbeispiel.

Random rnd = new Random();
int[] numbers = new int[4];
int total = 0;
for (int ctr = 0; ctr <= 2; ctr++)
{
    int number = rnd.Next(1001);
    numbers[ctr] = number;
    total += number;
}
numbers[3] = total;
object[] values = new object[numbers.Length];
numbers.CopyTo(values, 0);
Console.WriteLine("{0} + {1} + {2} = {3}", values);
open System

let rnd = Random()
let numbers = Array.zeroCreate<int> 4
let mutable total = 0
for i = 0 to 2 do
   let number = rnd.Next 1001
   numbers[i] <- number
   total <- total + number
numbers[3] <- total
let values = Array.zeroCreate<obj> numbers.Length
numbers.CopyTo(values, 0)
Console.WriteLine("{0} + {1} + {2} = {3}", values)
Imports System.Collections.Generic

Module Example6
    Public Sub Main()
        Dim rnd As New Random()
        Dim numbers(3) As Integer
        Dim total As Integer = 0
        For ctr = 0 To 2
            Dim number As Integer = rnd.Next(1001)
            numbers(ctr) = number
            total += number
        Next
        numbers(3) = total
        Dim values(numbers.Length - 1) As Object
        numbers.CopyTo(values, 0)
        Console.WriteLine("{0} + {1} + {2} = {3}", values)
    End Sub
End Module