Поделиться через


Составное форматирование

Обновлен: Ноябрь 2007

В качестве входных данных для составного форматирования в .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}}}", который должен вывести открывающую фигурную скобку, числовое значение, отформатированное в десятичном виде, и закрывающую фигурную скобку. В действительности элемент форматирования будет интерпретирован следующим образом:

  1. Первые две открывающие фигурные скобки ("{{") составляют escape-последовательность, которая дает в итоге одиночную открывающую фигурную скобку.

  2. Следующие три знака ("{0:") воспринимаются как начало элемента форматирования.

  3. Следующий знак ("D") должен интерпретироваться как указатель на десятичный числовой формат, но стоящая за ним пара фигурных скобок ("}}") дает в результате одиночную фигурную скобку. Поскольку результирующая строка ("D}") не является стандартным описателем числового формата, то она будет интерпретирована как строка пользовательского формата, что приведет к выводу строки "D}".

  4. Последняя фигурная скобка ("}") интерпретируется как конец элемента форматирования.

  5. Итоговый результат, который будет выведен — строка "{D}". Числовое значение, которое требовалось отформатировать, выведено не будет.

Одним из способов избежать неправильной интерпретации фигурных скобок и элементов форматирования при написании кода является раздельное форматирование фигурных скобок и элементов форматирования. Это означает, что первая операция форматирования должна выводить строку с открывающей фигурной скобкой, следующая операция — результат обработки элемента форматирования, а последняя операция — строку с закрывающей фигурной скобкой.

Порядок обработки

При форматировании значения null (Nothing в языке Visual Basic) возвращается пустая строка ("").

Если форматируемый тип реализует интерфейс 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)
int MyInt = 100;
Console.WriteLine("{0:C}", MyInt);

На тех компьютерах, где выбраны языковые и региональные параметры "Английский (США)", этот код будет выводить на консоль строку $100.00.

В следующем примере демонстрируется форматирование нескольких объектов, в том числе форматирование одного и того же объекта двумя разными способами.

Dim myName As String = "Fred"
String.Format("Name = {0}, hours = {1:hh}, minutes = {1:mm}",
      myName, DateTime.Now)
string myName = "Fred";
String.Format("Name = {0}, hours = {1:hh}, minutes = {1:mm}",
      myName, DateTime.Now);

Результатом обработки приведенной выше строки станет строка "Name = Fred, hours = 07, minutes = 23", числа в которой соответствуют текущему времени.

Ниже приведен пример использования выравнивания при форматировании. Форматируемые аргументы разделены знаками вертикальной черты ("|"), подчеркивающими полученное выравнивание.

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)

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)
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);

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);

При выборе языка и региональных параметров "Английский (США)" этот код выведет на консоль следующий текст. При выборе различных языковых и региональных параметров знаки денежных единиц и разделители также различаются.

First Name = |          Fred|
Last Name = |         Opals|
Price = |           $100.00|
First Name = |Fred      |
Last Name = |Opals     |
Price = |$100.00   |

См. также

Основные понятия

Общие сведения о форматировании

Ссылки

Console.Writeline

String.Format

System.IO

Другие ресурсы

Типы форматирования