Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Dieser Artikel enthält ergänzende Hinweise zur Referenzdokumentation für diese API.
Von Bedeutung
Anstatt die String.Format-Methode oder zusammengesetzte Formatzeichenfolgen aufzurufen, können Sie interpolierte Zeichenfolgen verwenden, wenn ihre Sprache sie unterstützt. 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
Formatierung steuern
Abstand steuern
Steuerelementausrichtung
Steuern der Anzahl ganzer Ziffern
Kontrollieren Sie die Anzahl der Stellen nach dem Dezimaltrennzeichen
Einschließen geschweifter Klammern in die Ergebniszeichenfolge
Formatzeichenfolgen kulturempfindlich machen
Formatzeichenfolgen kulturempfindlich machen
Anpassen des Formatierungsvorgangs
Ein benutzerdefinierter Formatierungsvorgang
Abfanganbieter und Formatierer für römische Zahlen
Erste Schritte mit der String.Format-Methode
Verwenden Sie String.Format, 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. 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 aufrufen; 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'
Zahlreiche Typen unterstützen Formatzeichenfolgen, einschließlich aller numerischen Typen (sowohl Standard- als auch benutzerdefinierte Formatzeichenfolgen), aller Datums- und Uhrzeitangaben (sowohl Standard- als auch benutzerdefinierte Formatzeichenfolgen), Zeitintervalle (sowohl Standard- als auch benutzerdefinierte Formatzeichenfolgen), alle Aufzählungstypen und GUIDs. Sie können auch Unterstützung für Formatzeichenfolgen zu Ihren eigenen Typen hinzufügen.
Steuerung der Abstände
Sie können die Breite der Zeichenfolge definieren, die in die Ergebniszeichenfolge eingefügt wird, indem Sie eine Syntax wie {0,12}
verwenden, die eine Zeichenfolge mit 12 Zeichen einfügt. 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
Steuern der Ausrichtung
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 sowohl Labels als auch Daten linksbündig ausgerichtet werden.
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 zusammengesetzte Formatierungsmerkmal. Für weitere Informationen siehe Composite Formatting.
Welche Methode soll ich aufrufen?
Zielsetzung | Aufzurufende Methode |
---|---|
Formatieren Sie ein oder mehrere Objekte mithilfe der Konventionen der aktuellen Kultur. | Mit Ausnahme der Überladungen, die einen provider Parameter enthalten, enthalten die verbleibenden Format Überladungen einen String Parameter, gefolgt von einem oder mehreren Objektparametern. Aus diesem Grund 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 Grund müssen Sie nicht bestimmen, welche spezifische 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 die zusammengesetzte Formatierungsfunktion, um nullbasiert indizierte Platzhalter, die als Formatelemente bezeichnet werden, in eine zusammengesetzte Formatzeichenfolge einzufügen. Zur Laufzeit wird jedes Formatelement durch die Zeichenfolgendarstellung des entsprechenden Arguments in einer Parameterliste ersetzt. Wenn der Wert des Arguments null
ist, wird das Formatelement durch String.Empty ersetzt. 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[,width][:formatString]}
Klammern geben optionale Elemente an. Die öffnenden und schließenden geschweiften Klammern sind erforderlich. (Informationen zum Einfügen einer literalen öffnenden oder schließenden geschweiften Klammer in die Formatzeichenfolge finden Sie im Artikel Kombinierte Formatierung im Abschnitt Versehen von geschweiften Klammern mit Escapezeichen.
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.
width
Wahlfrei. 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 weglassen width
, wird die Zeichenfolgendarstellung des entsprechenden Arguments in ein Feld ohne führende oder nachfolgende Leerzeichen eingefügt.
Wenn der Wert width
kleiner als die Länge des einzufügenden Arguments ist, wird ignoriert, width
und die Länge der Zeichenfolgendarstellung des Arguments wird als Feldbreite verwendet.
formatString
Wahlfrei. Eine Zeichenfolge, die das Format der Ergebniszeichenfolge des entsprechenden Arguments angibt. Wenn Sie weglassen formatString
, wird die parameterlose ToString
Methode des entsprechenden Arguments aufgerufen, um die Zeichenfolgendarstellung zu erzeugen. Wenn Sie angeben formatString
, muss das Argument, auf das vom Formatelement verwiesen wird, die IFormattable Schnittstelle implementieren. Zu den Typen, die Formatzeichenfolgen unterstützen, gehören:
Alle integrale Typen und Gleitkommatypen. (Siehe Standardmäßige numerische Formatzeichenfolgen und benutzerdefinierte numerische Formatzeichenfolgen.)
DateTime und DateTimeOffset. (Siehe Standardzeichenfolgen für Datums- und Uhrzeitformat und benutzerdefinierte Datums- und Uhrzeitformatzeichenfolgen.)
Alle Enumerationstypen. (Siehe Enumerationsformatzeichenfolgen.)
TimeSpan-Werte. (Siehe StandardtimeSpan-Formatzeichenfolgen und benutzerdefinierte TimeSpan-Formatzeichenfolgen.)
Guids. (Siehe die Guid.ToString(String) Methode.)
Ein benutzerdefinierter Typ kann jedoch IFormattable implementieren oder die Implementierung eines vorhandenen Typs IFormattable erweitern.
Im folgenden Beispiel werden die width
und formatString
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 %
Wie Argumente formatiert werden
Formatelemente werden vom Anfang der Zeichenfolge aus sequenziell 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
null
ist, fügt die Methode String.Empty in die Ergebniszeichenfolge ein. Sie müssen sich nicht mit der Behandlung von NullReferenceException bei Nullargumenten 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 einformatString
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 überschreibt oder von einer Implementierung der Basisklasse 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.
format
kann jedoch mehr Formatelemente enthalten, 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 von Format aufrufen, die 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:
- CultureInfo. Die GetFormat Methode gibt ein kulturspezifisches NumberFormatInfo Objekt zum Formatieren numerischer Werte und eines kulturspezifischen DateTimeFormatInfo Objekts zum Formatieren von Datums- und Uhrzeitwerten zurück.
- DateTimeFormatInfo, die für kulturspezifische Formatierung von Datums- und Uhrzeitwerten verwendet wird. Die GetFormat Methode gibt sich selbst zurück.
- NumberFormatInfo, die für kulturspezifische Formatierung numerischer Werte verwendet wird. Die GetFormat(Type) Methode gibt sich selbst zurück.
Benutzerdefinierte Formatierungsvorgänge
Sie können auch eine der Überladungen der Format-Methode aufrufen, die ü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 Durchführen einer benutzerdefinierten Formatierung muss das provider
Argument sowohl die IFormatProvider als auch die ICustomFormatter Schnittstellen implementieren. Wenn die Format Methode als ICustomFormatter Argument eine provider
Implementierung übergeben wird, ruft die Methode ihre Format Implementierung auf und fordert ein Objekt vom Typ IFormatProvider.GetFormat an. 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: Abfanganbieter und Formatierer für römische Zahlen
In diesem Beispiel wird ein benutzerdefinierter Formatanbieter definiert, der die ICustomFormatter und IFormatProvider Schnittstellen implementiert, um zwei Dinge zu tun:
- 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 gegenüber Aufrufen der String.Format
-Methode?
Die Zeichenfolgeninterpolation weist folgende Merkmale auf:
- 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. B. die Console.WriteLine-Methode oder die StringBuilder.AppendFormat-Methode.
- Besser lesbar. Da der in eine Zeichenfolge einzufügende Ausdruck im interpolierten Ausdruck und nicht in einer Argumentliste angezeigt wird, sind interpolierte Zeichenfolgen einfacher zu codieren und zu lesen. Interpolierte Zeichenfolgen können 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?
- Alle integralen und Gleitkommatypen finden Sie unter "Standard Numeric Format Strings " und "Custom Numeric Format Strings".
- Datums- und Uhrzeitwerte finden Sie unter Standard-Datums- und Uhrzeitformatzeichenfolgen sowie benutzerdefinierte Datums- und Uhrzeitformatzeichenfolgen.
- Enumerationswerte finden Sie unter Enumerationsformatzeichenfolgen.
- Werte TimeSpan finden Sie unter "Standard TimeSpan Format Strings " und "Custom TimeSpan Format Strings".
- Für Guid-Werte siehe den Abschnitt "Hinweise" auf der Guid.ToString(String)-Referenzseite.
Wie kann ich die Ausrichtung der Ergebniszeichenfolgen steuern, die Formatelemente ersetzen?
Die allgemeine Syntax eines Formatelements lautet:
{index[,width][: formatString]}
width
ist eine signierte ganze Zahl, die die Feldbreite definiert. Wenn dieser Wert negativ ist, wird Text im Feld linksbündig ausgerichtet. Ist er positiv, wird Text rechtsbündig ausgerichtet.
Wie kann ich 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
Wie kann ich 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 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.
Wie füge ich literale geschweifte Klammern („{“ und „}“) in die Ergebniszeichenfolge ein?
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. Damit sie buchstäblich interpretiert wird, muss sie mit Escapezeichen versehen werden. Sie versehen eine geschweifte Klammer mit Escapezeichen, indem Sie eine weitere geschweifte Klammer („{{“ und „}}“ anstelle von „{“ und „}“) wie im folgenden Methodenaufruf 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 mit Escapezeichen versehene geschweifte Klammern werden jedoch leicht falsch interpretiert. Es wird empfohlen, geschweifte Klammern zur Formatliste hinzuzufügen 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 mit einem Escapezeichen versehenes linkes oder rechtes geschweiftes Klammerzeichen einzuschließen, wird ebenfalls FormatException ausgelöst. Gelegentlich ist die Ausnahme das Ergebnis eines Tippfehlers; ein typischer Fehler ist beispielsweise, "[" (die linke Klammer) anstelle von "{" (die linke geschweifte Klammer) falsch zu tippen.
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($"{numbers} + {1} + {2} = {3}");
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. Im folgenden Beispiel wird eine Implementierung bereitgestellt.
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($"{values} + {1} + {2} = {3}");
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