Złożone formatowanie
Funkcja formatowania złożonego platformy .NET przyjmuje listę obiektów i ciąg formatu złożonego jako dane wejściowe. Ciąg formatu złożonego składa się ze stałego tekstu połączonego z indeksowanym symbolami zastępczymi, nazywanymi elementami formatu. Te elementy formatu odpowiadają obiektom na liście. Operacja formatowania zwraca ciąg wynikowy, który składa się z oryginalnego stałego tekstu zmieszanego z ciągiem reprezentującym obiekty na liście.
Ważne
Zamiast używać ciągów formatu złożonego, można użyć ciągów interpolowanych, jeśli używany język i jego wersja obsługują te ciągi . Ciąg interpolowany zawiera wyrażenia interpolowane. Każde wyrażenie interpolowane jest rozpoznawane przy użyciu wartości wyrażenia i uwzględniane w ciągu wynikowym po przypisaniu ciągu. Aby uzyskać więcej informacji, zobacz Interpolacja ciągów (odwołanie w C#) i ciągi interpolowane (odwołanie w języku Visual Basic).
Następujące metody obsługują funkcję formatowania złożonego:
- String.Format, który zwraca sformatowany ciąg wyników.
- StringBuilder.AppendFormat, który dołącza sformatowany ciąg wynikowy StringBuilder do obiektu.
- Niektóre przeciążenia Console.WriteLine metody, które wyświetlają sformatowany ciąg wyników w konsoli.
- Niektóre przeciążenia TextWriter.WriteLine metody, które zapisują sformatowany ciąg wynikowy do strumienia lub pliku. Klasy pochodzące z TextWriterklasy , takich jak StreamWriter i HtmlTextWriter, również współdzielą tę funkcję.
- Debug.WriteLine(String, Object[]), który zwraca sformatowany komunikat do śledzenia odbiorników.
- Metody Trace.TraceError(String, Object[]), Trace.TraceInformation(String, Object[])i Trace.TraceWarning(String, Object[]) , które wyświetlają sformatowane komunikaty w celu śledzenia odbiorników.
- Metoda TraceSource.TraceInformation(String, Object[]) , która zapisuje metodę informacyjną w celu śledzenia odbiorników.
Ciąg formatu złożonego
Ciąg formatu złożonego i lista obiektów są używane jako argumenty metod, które obsługują funkcję formatowania złożonego. Ciąg formatu złożonego składa się z zera lub większej liczby serii stałego tekstu zmieszanego z co najmniej jednym elementem formatu. Stały tekst to dowolnie wybrany ciąg, a każdy element formatu odpowiada obiektowi lub strukturze opakowanej na liście. Reprezentacja ciągu każdego obiektu zastępuje odpowiedni element formatu.
Rozważmy następujący Format fragment kodu:
string.Format("Name = {0}, hours = {1:hh}", "Fred", DateTime.Now);
String.Format("Name = {0}, hours = {1:hh}", "Fred", DateTime.Now)
Stały tekst to Name =
i , hours =
. Elementy formatu to {0}
, których indeks 0 odpowiada obiektowi name
, i {1:hh}
, którego indeks 1 odpowiada obiektowi DateTime.Now
.
Formatowanie składni elementu
Każdy element formatu ma następującą postać i składa się z następujących składników:
{index[,alignment][:formatString]}
Pasujące nawiasy klamrowe ({
i }
) są wymagane.
Składnik indeksu
Obowiązkowy składnik indeksu , który jest również nazywany specyfikatorem parametru, jest liczbą rozpoczynającą się od 0, która identyfikuje odpowiedni element na liście obiektów. Oznacza to, że element formatu, którego specyfikator parametru jest 0
formatuje pierwszy obiekt na liście. Element formatu, którego specyfikator parametru jest 1
formatuje drugi obiekt na liście itd. Poniższy przykład zawiera cztery specyfikatory parametrów, ponumerowane zero do trzech, aby reprezentować liczby pierwsze mniejsze niż 10:
string primes = string.Format("Four prime numbers: {0}, {1}, {2}, {3}",
2, 3, 5, 7);
Console.WriteLine(primes);
// The example displays the following output:
// Four prime numbers: 2, 3, 5, 7
Dim primes As String = String.Format("Four prime numbers: {0}, {1}, {2}, {3}",
2, 3, 5, 7)
Console.WriteLine(primes)
'The example displays the following output
' Four prime numbers 2, 3, 5, 7
Wiele elementów formatu może odwoływać się do tego samego elementu na liście obiektów, jeśli będą miały określony taki sam specyfikator parametru. Na przykład można sformatować tę samą wartość liczbową w formacie szesnastkowym, naukowym i liczbowym, określając ciąg formatu złożonego, taki jak "0x{0:X} {0:E} {0:N}"
, jak pokazano w poniższym przykładzie:
string multiple = string.Format("0x{0:X} {0:E} {0:N}",
Int64.MaxValue);
Console.WriteLine(multiple);
// The example displays the following output:
// 0x7FFFFFFFFFFFFFFF 9.223372E+018 9,223,372,036,854,775,807.00
Dim multiple As String = String.Format("0x{0:X} {0:E} {0:N}",
Int64.MaxValue)
Console.WriteLine(multiple)
'The example displays the following output
' 0x7FFFFFFFFFFFFFFF 9.223372E+018 9,223,372,036,854,775,807.00
Każdy element formatu może odwoływać się do dowolnego obiektu na liście. Jeśli na przykład istnieją trzy obiekty, możesz sformatować drugi, pierwszy i trzeci obiekt, określając ciąg formatu złożonego, taki jak {1} {0} {2}
. Obiekt, do którego nie odwołuje się element formatu, jest ignorowany. Element FormatException jest zgłaszany w czasie wykonywania, jeśli specyfikator parametru wyznacza element poza granicami listy obiektów.
Składnik wyrównania
Opcjonalny składnik wyrównania to podpisana liczba całkowita wskazująca preferowaną sformatowaną szerokość pola. Jeśli wartość wyrównania jest mniejsza niż długość sformatowanego ciągu, wyrównanie jest ignorowane, a długość sformatowanego ciągu jest używana jako szerokość pola. Sformatowane dane w polu są wyrównane do prawej, jeśli wyrównanie jest dodatnie i wyrównane do lewej, jeśli wyrównanie jest ujemne. Jeśli potrzebne jest dopełnienie, będą używane znaki odstępu. Przecinek jest wymagany, jeśli określono wyrównanie .
W poniższym przykładzie zdefiniowano dwie tablice, jedną zawierającą nazwy pracowników, a drugą zawierającą godziny pracy w ciągu dwóch tygodni. Ciąg formatu złożonego w lewo wyrównuje nazwy w polu 20 znaków i wyrówna ich godziny w polu 5-znakowym. Standardowy ciąg formatu "N1" formatuje godziny z jedną cyfrą ułamkową.
string[] names = { "Adam", "Bridgette", "Carla", "Daniel",
"Ebenezer", "Francine", "George" };
decimal[] hours = { 40, 6.667m, 40.39m, 82,
40.333m, 80, 16.75m };
Console.WriteLine("{0,-20} {1,5}\n", "Name", "Hours");
for (int counter = 0; counter < names.Length; counter++)
Console.WriteLine("{0,-20} {1,5:N1}", names[counter], hours[counter]);
// The example displays the following output:
// Name Hours
//
// Adam 40.0
// Bridgette 6.7
// Carla 40.4
// Daniel 82.0
// Ebenezer 40.3
// Francine 80.0
// George 16.8
Dim names As String() = {"Adam", "Bridgette", "Carla", "Daniel",
"Ebenezer", "Francine", "George"}
Dim hours As Decimal() = {40, 6.667D, 40.39D, 82,
40.333D, 80, 16.75D}
Console.WriteLine("{0,-20} {1,5}\n", "Name", "Hours")
For counter = 0 To names.Length - 1
Console.WriteLine("{0,-20} {1,5:N1}", names(counter), hours(counter))
Next
'The example displays the following output
' Name Hours
'
' Adam 40.0
' Bridgette 6.7
' Carla 40.4
' Daniel 82.0
' Ebenezer 40.3
' Francine 80.0
' George 16.8
Formatowanie składnika ciągu
Opcjonalny składnik formatString jest ciągiem formatu, który jest odpowiedni dla typu sformatowanego obiektu. Możesz określić następujące elementy:
- Standardowy lub niestandardowy ciąg formatu liczbowego, jeśli odpowiadający mu obiekt jest wartością liczbową.
- Standardowy lub niestandardowy ciąg formatu daty i godziny, jeśli odpowiedni obiekt jest obiektem DateTime .
- Ciąg formatu wyliczenia, jeśli odpowiedni obiekt jest wartością wyliczenia.
Jeśli formatString nie jest określony, używany jest ogólny specyfikator formatu ("G") dla typu liczbowego, daty i godziny lub wyliczenia. Dwukropek jest wymagany, jeśli określono formatString .
W poniższej tabeli wymieniono typy lub kategorie typów w bibliotece klas platformy .NET, które obsługują wstępnie zdefiniowany zestaw ciągów formatu, i zawiera linki do artykułów, które zawierają listę obsługiwanych ciągów formatu. Formatowanie ciągów to rozszerzalny mechanizm, który umożliwia definiowanie nowych ciągów formatu dla wszystkich istniejących typów oraz definiowanie zestawu ciągów formatu obsługiwanych przez typ zdefiniowany przez aplikację.
Aby uzyskać więcej informacji, zobacz IFormattable artykuły i ICustomFormatter dotyczące interfejsu.
Typ lub kategoria typów | Zobacz |
---|---|
Typy dat i godzin (DateTime, DateTimeOffset) | Standardowe ciągi formatu data i godzina Niestandardowe ciągi formatu data i godzina |
Typy wyliczenia (wszystkie typy pochodzące z System.Enum) | Ciągi formatujące wyliczenia |
Typy liczbowe (BigInteger, Byte, DecimalInt64Int32Int16DoubleSingleUInt16SByte, ) UInt64UInt32 | Standardowe ciągi formatów liczbowych Niestandardowe ciągi formatujące liczby |
Guid | Guid.ToString(String) |
TimeSpan | Standardowe ciągi formatujące TimeSpan Niestandardowe ciągi formatujące TimeSpan |
Ucieczka nawiasów klamrowych
Klamrowe nawiasy otwierający i zamykający są interpretowane jako rozpoczęcie i zakończenie elementu formatu. Aby wyświetlić nawias klamrowy otwierający literał lub zamykający nawias klamrowy, należy użyć sekwencji ucieczki. Określ dwa otwierające nawiasy klamrowe ({{
) w stałym tekście, aby wyświetlić jeden otwierający nawias klamrowy ({
) lub dwa zamykające nawiasy klamrowe (}}
), aby wyświetlić jeden zamykający nawias klamrowy (}
).
Nawiasy klamrowe z elementem formatu są analizowane inaczej między platformami .NET i .NET Framework.
.NET
Nawiasy klamrowe można unikać wokół elementu formatu. Rozważmy na przykład element {{{0:D}}}
formatu , który ma na celu wyświetlenie nawiasu klamrowego otwierającego, wartości liczbowej sformatowanej jako liczba dziesiętna i zamykającego nawiasu klamrowego. Element formatu jest interpretowany w następujący sposób:
- Pierwsze dwa otwierające nawiasy klamrowe (
{{
) są ucieczki i dają jeden otwierający nawias klamrowy. - Następne trzy znaki (
{0:
) są interpretowane jako początek elementu formatu. - Następny znak (
D
) jest interpretowany jako specyfikator formatu dziesiętnego standardowego formatu liczbowego. - Następny nawias klamrowy (
}
) jest interpretowany jako koniec elementu formatu. - Ostatnie dwa nawiasy klamrowe zamykające są ucieczki i dają jeden zamykający nawias klamrowy.
- Wynik końcowy, który jest wyświetlany, to ciąg literału .
{6324}
int value = 6324;
string output = string.Format("{{{0:D}}}", value);
Console.WriteLine(output);
// The example displays the following output:
// {6324}
Dim value As Integer = 6324
Dim output As String = String.Format("{{{0:D}}}", value)
Console.WriteLine(output)
'The example displays the following output
' {6324}
.NET Framework
Nawiasy klamrowe w elemencie formatu są interpretowane sekwencyjnie w kolejności ich napotkania. Interpretowanie zagnieżdżonych nawiasów klamrowych nie jest obsługiwane.
Sposób interpretowania nawiasów klamrowych poprzedzonych znakiem ucieczki może prowadzić do nieoczekiwanych rezultatów. Rozważmy na przykład element {{{0:D}}}
formatu , który ma na celu wyświetlenie nawiasu klamrowego otwierającego, wartości liczbowej sformatowanej jako liczba dziesiętna i zamykającego nawiasu klamrowego. Jednak element formatu jest interpretowany w następujący sposób:
- Pierwsze dwa otwierające nawiasy klamrowe (
{{
) są ucieczki i dają jeden otwierający nawias klamrowy. - Następne trzy znaki (
{0:
) są interpretowane jako początek elementu formatu. - Następny znak (
D
) zostanie zinterpretowany jako specyfikator formatu dziesiętnego standardowego formatu liczbowego, ale następne dwa nawiasy klamrowe (}}
) uniknęły pojedynczego nawiasu klamrowego. Ponieważ wynikowy ciąg (D}
) nie jest standardowym specyfikatorem formatu liczbowego, wynikowy ciąg jest interpretowany jako ciąg formatu niestandardowego, który oznacza wyświetlanie ciąguD}
literału . - Ostatni nawias klamrowy (
}
) jest interpretowany jako koniec elementu formatu. - Wynik końcowy, który jest wyświetlany, to ciąg literału .
{D}
Wartość liczbowa, która miała zostać sformatowana, nie jest wyświetlana.
int value = 6324;
string output = string.Format("{{{0:D}}}",
value);
Console.WriteLine(output);
// The example displays the following output:
// {D}
Dim value As Integer = 6324
Dim output As String = String.Format("{{{0:D}}}",
value)
Console.WriteLine(output)
'The example displays the following output:
' {D}
Jednym ze sposobów na napisanie kodu w celu uniknięcia błędnej interpretacji nawiasów klamrowych i elementów formatu jest oddzielne formatowanie nawiasów klamrowych i elementów. Oznacza to, że w pierwszej operacji formatowania wyświetl nawias klamrowy otwierający literał. W następnej operacji wyświetl wynik elementu formatu, a w końcowej operacji wyświetl nawias klamrowy zamykający literał. Poniższy przykład ilustruje to podejście:
int value = 6324;
string output = string.Format("{0}{1:D}{2}",
"{", value, "}");
Console.WriteLine(output);
// The example displays the following output:
// {6324}
Dim value As Integer = 6324
Dim output As String = String.Format("{0}{1:D}{2}",
"{", value, "}")
Console.WriteLine(output)
'The example displays the following output:
' {6324}
Kolejność przetwarzania
Jeśli wywołanie metody formatowania złożonego zawiera IFormatProvider argument, którego wartość nie null
jest , środowisko uruchomieniowe wywołuje jego IFormatProvider.GetFormat metodę w celu żądania ICustomFormatter implementacji. Jeśli metoda może zwrócić implementację ICustomFormatter , jest buforowana podczas wywołania metody formatowania złożonego.
Każda wartość na liście parametrów odpowiadająca elementowi formatu jest konwertowana na ciąg w następujący sposób:
Jeśli wartość do sformatowania to
null
, zwracany jest pusty ciąg String.Empty .Jeśli implementacja ICustomFormatter jest dostępna, środowisko uruchomieniowe wywołuje jego Format metodę. Środowisko uruchomieniowe przekazuje wartość elementu
formatString
formatu (lubnull
jeśli nie jest obecna) do metody . Środowisko uruchomieniowe przekazuje również implementację IFormatProvider do metody . Jeśli wywołanie ICustomFormatter.Format metody zwrócinull
metodę , wykonanie przejdzie do następnego kroku. W przeciwnym razie zwracany jest wynik ICustomFormatter.Format wywołania.Jeśli wartość implementuje IFormattable interfejs, wywoływana jest metoda interfejsu ToString(String, IFormatProvider) . Jeśli element jest obecny w elemencie formatu, wartość formatString jest przekazywana do metody .
null
W przeciwnym razie jest przekazywany. Argument IFormatProvider jest określany w następujący sposób:W przypadku wartości liczbowej, jeśli wywoływana jest metoda formatowania złożonego z argumentem innej niż null IFormatProvider , środowisko uruchomieniowe żąda NumberFormatInfo obiektu z jego IFormatProvider.GetFormat metody. Jeśli nie można go podać, jeśli wartość argumentu to
null
, lub jeśli metoda formatowania złożonego IFormatProvider nie ma parametru, NumberFormatInfo używany jest obiekt dla bieżącej kultury.Jeśli dla wartości daty i godziny wywoływana jest metoda formatowania złożonego z argumentem innej niż null IFormatProvider , środowisko uruchomieniowe żąda DateTimeFormatInfo obiektu z jego IFormatProvider.GetFormat metody. W następujących sytuacjach DateTimeFormatInfo obiekt bieżącej kultury jest używany:
- Metoda IFormatProvider.GetFormat nie może podać DateTimeFormatInfo obiektu.
- Wartość argumentu to
null
. - Metoda formatowania złożonego nie ma parametru IFormatProvider .
W przypadku obiektów innych typów, jeśli metoda formatowania złożonego jest wywoływana z argumentem IFormatProvider , jego wartość jest przekazywana bezpośrednio do implementacji IFormattable.ToString .
null
W przeciwnym razie jest przekazywany do implementacjiIFormattable.ToString.
Wywoływana jest metoda bez
ToString
parametrów typu, która zastępuje Object.ToString() lub dziedziczy zachowanie klasy bazowej. W takim przypadku ciąg formatu określony przezformatString
składnik w elemencie formatu, jeśli jest obecny, jest ignorowany.
Wyrównanie zostanie zastosowane po wykonaniu poprzednich kroków.
Przykłady kodu
W poniższym przykładzie pokazano jeden ciąg utworzony przy użyciu formatowania złożonego, a drugi utworzony przy użyciu metody obiektu ToString
. Oba typy formatowania dają równoważne wyniki.
string formatString1 = string.Format("{0:dddd MMMM}", DateTime.Now);
string formatString2 = DateTime.Now.ToString("dddd MMMM");
Dim formatString1 As String = String.Format("{0:dddd MMMM}", DateTime.Now)
Dim formatString2 As String = DateTime.Now.ToString("dddd MMMM")
Zakładając, że bieżący dzień to czwartek w maju, wartość obu ciągów w poprzednim przykładzie znajduje Thursday May
się w kulturze angielskiej USA.
Console.WriteLine uwidacznia tę samą funkcjonalność co String.Format. Jedyną różnicą między dwiema metodami jest to, że String.Format zwraca jego wynik jako ciąg, podczas gdy Console.WriteLine zapisuje wynik do strumienia wyjściowego skojarzonego z obiektem Console . W poniższym przykładzie użyto Console.WriteLine metody do sformatowania wartości myNumber
w walucie:
int myNumber = 100;
Console.WriteLine("{0:C}", myNumber);
// The example displays the following output
// if en-US is the current culture:
// $100.00
Dim myNumber As Integer = 100
Console.WriteLine("{0:C}", myNumber)
'The example displays the following output
'if en-US Is the current culture:
' $100.00
W poniższym przykładzie pokazano formatowanie wielu obiektów, w tym formatowanie jednego obiektu na dwa różne sposoby:
string myName = "Fred";
Console.WriteLine(string.Format("Name = {0}, hours = {1:hh}, minutes = {1:mm}",
myName, DateTime.Now));
// Depending on the current time, the example displays output like the following:
// Name = Fred, hours = 11, minutes = 30
Dim myName As String = "Fred"
Console.WriteLine(String.Format("Name = {0}, hours = {1:hh}, minutes = {1:mm}",
myName, DateTime.Now))
'Depending on the current time, the example displays output Like the following:
' Name = Fred, hours = 11, minutes = 30
W poniższym przykładzie pokazano użycie wyrównania w formatowaniu. Argumenty sformatowane są umieszczane między pionowymi znakami paska (|
), aby wyróżnić wynikowe wyrównanie.
string firstName = "Fred";
string lastName = "Opals";
int myNumber = 100;
string formatFirstName = string.Format("First Name = |{0,10}|", firstName);
string formatLastName = string.Format("Last Name = |{0,10}|", lastName);
string formatPrice = string.Format("Price = |{0,10:C}|", myNumber);
Console.WriteLine(formatFirstName);
Console.WriteLine(formatLastName);
Console.WriteLine(formatPrice);
Console.WriteLine();
formatFirstName = string.Format("First Name = |{0,-10}|", firstName);
formatLastName = string.Format("Last Name = |{0,-10}|", lastName);
formatPrice = string.Format("Price = |{0,-10:C}|", myNumber);
Console.WriteLine(formatFirstName);
Console.WriteLine(formatLastName);
Console.WriteLine(formatPrice);
// The example displays the following output on a system whose current
// culture is en-US:
// First Name = | Fred|
// Last Name = | Opals|
// Price = | $100.00|
//
// First Name = |Fred |
// Last Name = |Opals |
// Price = |$100.00 |
Dim firstName As String = "Fred"
Dim lastName As String = "Opals"
Dim myNumber As Integer = 100
Dim formatFirstName As String = String.Format("First Name = |{0,10}|", firstName)
Dim formatLastName As String = String.Format("Last Name = |{0,10}|", lastName)
Dim formatPrice As String = String.Format("Price = |{0,10:C}|", myNumber)
Console.WriteLine(formatFirstName)
Console.WriteLine(formatLastName)
Console.WriteLine(formatPrice)
Console.WriteLine()
formatFirstName = String.Format("First Name = |{0,-10}|", firstName)
formatLastName = String.Format("Last Name = |{0,-10}|", lastName)
formatPrice = String.Format("Price = |{0,-10:C}|", myNumber)
Console.WriteLine(formatFirstName)
Console.WriteLine(formatLastName)
Console.WriteLine(formatPrice)
'The example displays the following output on a system whose current
'culture Is en-US:
' First Name = | Fred|
' Last Name = | Opals|
' Price = | $100.00|
'
' First Name = |Fred |
' Last Name = |Opals |
' Price = |$100.00 |
Zobacz też
- WriteLine
- String.Format
- Interpolacja ciągów (C#)
- Interpolacja ciągów (Visual Basic)
- Formatowanie typów
- Standardowe ciągi formatów liczbowych
- Niestandardowe ciągi formatujące liczby
- Standardowe ciągi formatu data i godzina
- Niestandardowe ciągi formatu data i godzina
- Standardowe ciągi formatujące TimeSpan
- Niestandardowe ciągi formatujące TimeSpan
- Ciągi formatujące wyliczenia