Ответ 1
Похоже, вы неправильно понимаете дизайн инфраструктуры форматирования .NET Framework. ICustomFormatter
никогда не следует ссылаться на реализацию IFormattable.ToString
, поскольку это противоречит намеченной цели этого интерфейса.
IFormattable
Объект должен реализовывать только IFormattable
, если он знает, как отформатировать себя (в идеале он должен делегировать это другому классу, но здесь было бы намеренное соединение). Объект может знать, как отформатировать себя несколькими разными способами, поэтому строка формата позволяет выбирать между ними. Даже при этом все еще может быть недостающая информация, такие вещи, которые различаются по культуре. Поэтому есть второй параметр, который косвенно предоставляет такую информацию.
Тип, переданный в IFormatProvider.GetFormat
, предназначен для типа или интерфейса, специфичных для класса IFormatProvider
.
Например, встроенные числовые типы хотят получить экземпляр System.Globalization.NumberFormatInfo
, а связанные классы DateTime
хотят получить System.Globalization.DateTimeFormatInfo
.
Реализация IFormattable
Итак, представьте себе, что мы создаем новый класс самоформатов. Если он знает только один способ форматирования, он должен просто переопределить object.ToString()
и не более того. Если класс знает более одного способа форматирования, он должен реализовать IFormattable
.
Параметр format
Per документация IFormattable.ToString
поддерживается форматная строка "G"
(которая представляет общий формат) должна. Рекомендуется, чтобы строка нулевого или пустого формата была эквивалентна строке формата "G"
. Точное значение для нас в противном случае.
Параметр formatProvider
Если нам нужна какая-либо специфическая культура или которая в противном случае будет изменяться, нам нужно использовать параметр IFormatProvider
. Какой-то тип, который мы запрашиваем, используя IFormatProvider.GetFormat
. Если значение IFormatProvider
равно null, или если IFormatProvider.GetFormat
возвращает null для типа, который мы хотим, мы должны вернуться к некоторому источнику по умолчанию для этой различной информации.
Источник по умолчанию не обязательно должен быть статическим. Вполне возможно, что источником по умолчанию может быть пользовательский параметр в приложении, а formatProvider
используется для предварительного просмотра изменений параметров и/или когда для сериализации необходим фиксированный формат.
Также возможно, что форматирование может включать форматирование некоторого под-объекта. В этом случае вы, вероятно, захотите передать IFormatProvider
вниз. MSDN имеет отличный пример реализации IFormattable
, который показывает этот самый случай.
Другие ToString
перегрузки
При реализации IFormattable
важно, чтобы object.ToString()
было переопределено способом, эквивалентным следующему
public override string ToString()
{
return this.ToString(null, System.Globalization.CultureInfo.CurrentCulture);
}
Это гарантирует, что somestring + yourobject
эквивалентен string.Format("{0}{1}",somestring, yourobject)
, который ваши пользователи будут ожидать.
Для удобства пользователей вы должны, возможно, предоставить string ToString(string format)
. Кроме того, если ваш формат по умолчанию имеет различные компоненты, которые могут извлечь выгоду из IFormatProvider
, вы также можете предоставить public string ToString(IFormatProvider provider)
.
ICustomFormatter
Итак, что нам делать, если мы хотим отформатировать класс, который не знает, как отформатировать себя, или мы хотим использовать какой-то формат, не поддерживаемый самим классом. То есть, когда ICustomFormatter становится актуальным. IFormatProvider
, который может предоставить тип ICustomFormatter
, может быть передан как параметр IFormatProvider
в таких методах, как string.Format
и StringBuilder.AppendFormat
.
Предоставленный ICustomFormatter
имеет свой метод format
для каждого форматирования, который делает string.Format
. Если ICustomFormatter
не знаком с используемой строкой формата или не поддерживает этот тип, он просто передает IFormattable.ToString
или Object.ToString
. Документация ICustomFormatter
содержит список того, что необходимо, если вы форматируете объект, который еще не поддерживает форматирование, и что необходимо, если вы просто хотите добавить дополнительный формат для существующего IFormattable
. Он также дает пример добавления дополнительного формата.
Ссылка
Эта страница MSDN дает отличный обзор системы форматирования .NET и предоставляет ссылки на почти все другие релевантные страницы в MSDN. Это лучшее место для начала практически любого вопроса, связанного с форматированием.