Спецификаторы формата и глобализация

Часто возникает необходимость в специфичном форматировании данных, которые приложение отображает пользователям.

Например, может понадобиться отображать значение с плавающей точкой, представляющее некоторое вещественное значение, в экспоненциальной форме или в форме с фиксированной точкой.

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

Программистам на С для форматирования значений доступно семейство функций printf, но ему недостает некоторых специфичных для локали возможностей.

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

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

Соображения, связанные с различными культурами, важно принимать во внимание еще на ранних стадиях цикла разработки. Многие разработчики склонны откладывать на потом решение проблем, связанных с глобализацией. Но если вы заметили, проектировщики .NET Framework приложили массу усилий к созданию развитой библиотеки, позволяющей решать проблемы глобализации.

Богатство и ширина охвата API-интерфейса глобализации указывает на ее сложность. Учитывая соображения глобализации на ранних стадиях разработки, вы избавляете себя от неприятностей, которые неизбежно возникнут позже.

Object.ToString, IFormattable и Culturelnfo

Каждый объект наследует метод по имени ToString от System.Object. Возможно, вы уже знакомы с ним. Получать строковое представление объекта для вывода, пусть даже только для отладочных целей, исключительно удобно.

Для собственных специальных классов реализация по умолчанию метода ToString просто возвращает тип самого объекта. Чтобы этот метод выводил что-то полезное, потребуется предусмотреть собственное переопределение. Как и можно было ожидать, это сделано во всех встроенных типах.

Поэтому, в результате вызова ToString на экземпляре System.Int32 получается строковое представление хранимого в нем значения. Но если понадобится строковое представление шестнадцатеричного формата значения, то Object.ToString в этом не поможет, поскольку не предусматривает возможности запросить нужный формат.

Должен существовать другой способ строкового представления объекта. Фактически он есть, и предусматривает реализацию интерфейса IFormattable, который выглядит следующим образом:

public interface IFormattable
{
string ToString( string format, IFormatProvider formatProvider )
}

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

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

Когда в этом параметре передается null, то используемым IFormattable.ToString поставщиком формата обычно является экземпляр Culturelnfo, возвращаемый методом System.Globalization.Culturelnfo. CurrentCulture.

Этот экземпляр Culturelnfo идентифицирует культуру, используемую текущим потоком. Однако есть возможность переопределить ее, создав новый экземпляр Culturelnfo и передав его конструктору строку, описывающую информацию о желаемой локали, как указано в стандарте RFC 1766 (например, en-US для английского языка, используемого в США).

За дополнительной информацией об именах культур обращайтесь к описанию класса Culturelnfo в документации MSDN. И, наконец, можно даже предоставить нейтральный по отношению к культуре экземпляр Culturelnfo, передав ему объект, выданный методом Culturelnfo. Invariant Culture.

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

Каждый экземпляр Culturelnfo содержит в себе специфичные экземпляры DateTimeFormatlnfo, NumberFormatlnfо, Textlnfo и Compare Info, присущие представленному языку и региону.

Как только реализация IFormattable.ToString получает корректный поставщик формата — передан он явно или присоединен к текущему потоку — она может опрашивать этого поставщика, вызывая метод IFormatProvider.GetFormat. Форматеры реализованы .NET Framework в типах NumberFormatlnf о и DateTimeFormatlnfo.

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

Предположим, что необходимо преобразовать числовое значение с плавающей точкой в строку. Поток выполнения реализации IFormattable.ToString для System. Double выполняет перечисленные ниже основные шаги.

1. Реализация получает ссылку на тип IFormatProvider, который является либо переданным, либо присоединенным к текущему потоку, если передан null.

2. Запрашивается поставщик формата для экземпляра типа NumberFormatlnf о через вызов IFormatProvider.GetFormat. Поставщик формата инициализирует свойства экземпляра NumberFormatlnf о на основе представляемой им культуры.

3. Используется экземпляр NumberFormatlnf о для соответствующего форматирования числа, создавая строковое его представление на основе спецификации форматной строки.

Вы можете следить за любыми ответами на эту запись через RSS 2.0 ленту. Вы можете оставить ответ, или trackback с вашего собственного сайта.

Оставьте отзыв

XHTML: Вы можете использовать следующие теги: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

 
Rambler's Top100