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:
Alle integralen und Gleitkommatypen. (Siehe Zeichenfolgen im numerischen Standardformat und benutzerdefinierte Zahlenformatzeichenfolgen.)
DateTime und DateTimeOffset. (Siehe Standard-Datums- und Uhrzeitformatzeichenfolgen und benutzerdefinierte Datums- und Uhrzeitformatzeichenfolgen.)
Alle Enumerationstypen. (Siehe Enumeration Format Strings.)
TimeSpan-Werte sind. (Siehe Standardmäßige TimeSpan-Formatzeichenfolgen und benutzerdefinierte TimeSpan-Formatzeichenfolgen.)
GUIDs. (Siehe die Guid.ToString(String) Methode.)
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:
- 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 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?
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".
Werte Guid finden Sie im Abschnitt "Hinweise" der Guid.ToString(String) Referenzseite.
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