Составное форматирование
В качестве входных данных для составного форматирования в .NET Framework используется список объектов и строка составного формата. Строка составного формата состоит из фиксированного текста, в который включены индексированные местозаполнители, которые называются элементами форматирования и соответствуют объектам из списка. Операция форматирования создает результирующую строку, состоящую из исходного фиксированного текста, в который включено строковое представление объектов из списка.
Составное форматирование поддерживается такими методами, как Format и AppendFormat, а также некоторыми перегрузками методов WriteLine и TextWriter.WriteLine. Метод String.Format возвращает отформатированную результирующую строку, метод AppendFormat добавляет отформатированную результирующую строку к объекту StringBuilder, метод Console.WriteLine выводит отформатированную результирующую строку на консоль, а метод TextWriter.WriteLine записывает отформатированную результирующую строку в поток или файл.
Строка составного формата
Строка составного формата и список объектов используются в качестве аргументов методов, поддерживающих составное форматирование. Строка составного формата состоит из блоков фиксированного текста числом от нуля и больше, перемежаемых одним или несколькими элементами форматирования. Фиксированным текстом может являться произвольная строка, а каждый элемент форматирования должен соответствовать объекту или упакованной структуре из списка. В ходе составного форматирования создается новая результирующая строка, в которой все элементы форматирования заменены на строковое представление соответствующих объектов из списка.
Рассмотрим следующий фрагмент кода Format.
Dim myName As String = "Fred"
String.Format("Name = {0}, hours = {1:hh}", myName, DateTime.Now)
string myName = "Fred";
String.Format("Name = {0}, hours = {1:hh}", myName, DateTime.Now);
Фиксированным текстом здесь является "Name = " и ", hours = ". Элементы форматирования здесь — это "{0}" c индексом 0, который соответствует объекту myName, и "{1:hh}" с индексом 1, который соответствует объекту DateTime.Now.
Синтаксис элементов форматирования
Каждый элемент форматирования имеет следующий вид и состоит из следующих компонентов:
{index[,alignment][:formatString]}
Парные фигурные скобки ("{" и "}") здесь обязательны.
Индекс
Обязательный компонент index, также называемый описателем параметра, — это число, определяющее соответствующий объект из списка; индексация элементов ведется от нуля. Иными словами, элемент форматирования с индексом 0 отвечает за формат первого объекта в списке, элемент форматирования с индексом 1 служит для форматирования второго объекта в списке и т. д.
На один и тот же элемент в списке объектов может ссылаться сразу несколько элементов форматирования — достигается это путем задания одинакового описателя параметра. Например, одно и то же числовое значение можно отформатировать в шестнадцатеричном, экспоненциальном и десятичном виде путем задания следующей строки составного форматирования: "{0:X} {0:E} {0:N}".
Любой элемент форматирования может ссылаться на произвольный объект списка. Например, если имеется три объекта, то можно отформатировать сначала второй, а затем первый и третий объекты, задав следующую строку составного форматирования: "{1} {0} {2}". Объекты, на которые не ссылаются элементы форматирования, пропускаются. Если описатель параметра ссылается на элемент за пределами списка объектов, то во время выполнения создается исключение.
Выравнивание
Необязательный компонент alignment — это целое число со знаком, которое служит для указания желательной ширины поля форматирования. Если значение alignment меньше длины форматируемой строки, то alignment пропускается, и в качестве значения ширины поля используется длина форматируемой строки. Форматируемые данные выравниваются в поле по правому краю, если alignment имеет положительное значение, или по левому краю, если alignment имеет отрицательное значение. При необходимости отформатированная строка дополняется пробелами. При использовании компонента alignment необходимо поставить запятую.
Компонент строки формата
Необязательный компонент formatString — это строка формата, соответствующая типу форматируемого объекта. Если соответствующий объект является объектом DateTime, то используется строка стандартного или настраиваемого формата чисел, а если соответствующий объект является значением перечисления, то используется строка формата перечисления. Если компонент formatString не задан, то для числовых значений, значений даты и времени, а также перечислений используется общий формат ("G"). При использовании компонента formatString необходимо поставить двоеточие.
Примечание |
---|
Полный список строк стандартного и настраиваемого формата чисел см. в разделах Строки стандартных числовых форматов и Строки настраиваемых числовых форматов.Полный список строк стандартного формата даты и времени см. в разделах Строки стандартных форматов даты и времени и Строки настраиваемых форматов даты и времени. |
Оформление фигурных скобок
Начало и конец элемента форматирования обозначаются соответственно открывающей и закрывающей фигурной скобкой. Это означает, что для вывода открывающих и закрывающих фигурных скобок необходимо использовать escape-последовательности. Для вывода открывающей или закрывающей фигурной скобки в фиксированном тексте следует поставить две открывающие или, соответственно, закрывающие фигурные скобки подряд ("{{" или "}}"). Фигурные скобки в элементе форматирования интерпретируются последовательно в порядке их обнаружения. Интерпретация вложенных скобок не поддерживается.
Порядок интерпретации скобок может привести к непредвиденным результатам. Например, рассмотрим элемент форматирования "{{{0:D}}}", который должен вывести открывающую фигурную скобку, числовое значение, отформатированное в десятичном виде, и закрывающую фигурную скобку. В действительности элемент форматирования будет интерпретирован следующим образом:
Первые две открывающие фигурные скобки ("{{") составляют escape-последовательность, которая дает в итоге одиночную открывающую фигурную скобку.
Следующие три знака ("{0:") воспринимаются как начало элемента форматирования.
Следующий знак ("D") должен интерпретироваться как указатель на десятичный числовой формат, но стоящая за ним пара фигурных скобок ("}}") дает в результате одиночную фигурную скобку. Поскольку результирующая строка ("D}") не является стандартным описателем числового формата, то она будет интерпретирована как строка пользовательского формата, что приведет к выводу строки "D}".
Последняя фигурная скобка ("}") интерпретируется как конец элемента форматирования.
Итоговый результат, который будет выведен — строка "{D}". Числовое значение, которое требовалось отформатировать, выведено не будет.
Одним из способов избежать неправильной интерпретации фигурных скобок и элементов форматирования при написании кода является раздельное форматирование фигурных скобок и элементов форматирования. Это означает, что первая операция форматирования должна выводить строку с открывающей фигурной скобкой, следующая операция — результат обработки элемента форматирования, а последняя операция — строку с закрывающей фигурной скобкой. Этот подход показан в приведенном ниже примере.
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}
int value = 6324;
string output = string.Format("{0}{1:D}{2}",
"{", value, "}");
Console.WriteLine(output);
// The example displays the following output:
// {6324}
Порядок обработки
Каждое значение в списке параметров, соответствующее элементу форматирования, преобразуется в строку выполнением шагов в следующем списке. Если любое условие на первых трех шагах принимает логическое значение "true", строковое представление значения возвращается на этот шаг, и последующие шаги не выполняются.
Если форматируемое значение является значением null, возвращается пустая строка ("").
Если метод составного форматирования включает параметр типа IFormatProvider, который также реализует интерфейс ICustomFormatter, значение передается в метод ICustomFormatter.Format.
Если значение реализует интерфейс IFormattable, вызывается его метод IFormattable.ToString.
Вызывается метод типа ToString, который или переопределяется из класса Object, или от него наследуется.
После выполнения предшествующих шагов производится выравнивание.
Примеры кода
В приведенном ниже примере одна строка создается с помощью составного форматирования, а другая – с помощью метода ToString. Оба способа форматирования дают идентичные результаты.
Dim FormatString1 As String = String.Format("{0:dddd MMMM}", DateTime.Now)
Dim FormatString2 As String = DateTime.Now.ToString("dddd MMMM")
string FormatString1 = String.Format("{0:dddd MMMM}", DateTime.Now);
string FormatString2 = DateTime.Now.ToString("dddd MMMM");
Предположим, что сейчас май, а текущий день недели – четверг; тогда значение обеих строк в предыдущем примере будет равно Thursday May для языка и региональных параметров "Английский (США)".
Метод Console.WriteLine предоставляет те же функциональные возможности, что и метод String.Format. Единственное различие между этими двумя методами состоит в том, что метод String.Format возвращает результаты в виде строки, а метод Console.WriteLine записывает результаты в поток вывода, связанный с объектом Console. В следующем примере для форматирования значения переменной MyInt в виде денежного значения используется метод Console.WriteLine.
Dim MyInt As Integer = 100
Console.WriteLine("{0:C}", MyInt)
' The example displays the following output
' if en-US is the current culture:
' $100.00
int MyInt = 100;
Console.WriteLine("{0:C}", MyInt);
// The example displays the following output
// if en-US is the current culture:
// $100.00
В следующем примере демонстрируется форматирование нескольких объектов, в том числе форматирование одного и того же объекта двумя разными способами.
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
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 myFName As String = "Fred"
Dim myLName As String = "Opals"
Dim myInt As Integer = 100
Dim FormatFName As String = String.Format("First Name = |{0,10}|", myFName)
Dim FormatLName As String = String.Format("Last Name = |{0,10}|", myLName)
Dim FormatPrice As String = String.Format("Price = |{0,10:C}|", myInt)
Console.WriteLine(FormatFName)
Console.WriteLine(FormatLName)
Console.WriteLine(FormatPrice)
Console.WriteLine()
FormatFName = String.Format("First Name = |{0,-10}|", myFName)
FormatLName = String.Format("Last Name = |{0,-10}|", myLName)
FormatPrice = String.Format("Price = |{0,-10:C}|", myInt)
Console.WriteLine(FormatFName)
Console.WriteLine(FormatLName)
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 |
string myFName = "Fred";
string myLName = "Opals";
int myInt = 100;
string FormatFName = String.Format("First Name = |{0,10}|", myFName);
string FormatLName = String.Format("Last Name = |{0,10}|", myLName);
string FormatPrice = String.Format("Price = |{0,10:C}|", myInt);
Console.WriteLine(FormatFName);
Console.WriteLine(FormatLName);
Console.WriteLine(FormatPrice);
Console.WriteLine();
FormatFName = String.Format("First Name = |{0,-10}|", myFName);
FormatLName = String.Format("Last Name = |{0,-10}|", myLName);
FormatPrice = String.Format("Price = |{0,-10:C}|", myInt);
Console.WriteLine(FormatFName);
Console.WriteLine(FormatLName);
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 |
См. также
Ссылки
Основные понятия
Строки стандартных числовых форматов
Строки настраиваемых числовых форматов
Строки стандартных форматов даты и времени
Строки настраиваемых форматов даты и времени