Строка.Формат - как это работает и как реализовать пользовательские formatstrings


С String.Format() можно отформатировать например DateTime объекты по-разному. Каждый раз, когда я ищу нужный формат, мне нужно искать вокруг в Интернете. Почти всегда я нахожу пример, который могу использовать. Например:

String.Format("{0:MM/dd/yyyy}", DateTime.Now);          // "09/05/2012"

но я понятия не имею, как это работает и какие классы поддерживают эти "волшебные" дополнительные строки.

Итак, мои вопросы:

  1. как String.Format карта дополнительная информация MM/dd/yyyy в результат строки?
  2. все ли объекты Microsoft поддерживают эту функцию?
    Это где-то задокументировано?
  3. можно ли сделать что-то вроде этого:
    String.Format("{0:MyCustomFormat}", new MyOwnClass())
7 76

7 ответов:

String.Format соответствует каждому из токенов внутри строки ({0} etc) против соответствующего объекта:http://msdn.microsoft.com/en-us/library/system.string.format.aspx

дополнительно предоставляется строка формата:

{ index[,alignment][ : formatString] }

если formatString предоставляется, соответствующий объект должен реализовать IFormattable и в частности ToString метод, который принимает formatString и возвращает соответствующий формат строка:http://msdn.microsoft.com/en-us/library/system.iformattable.tostring.aspx

An IFormatProvider может также использоваться, который может использоваться, чтобы захватить основные стандарты форматирования/дефолтов и т. д. Примеры здесь и здесь.

Итак, ответы на ваши вопросы по порядку:

  1. использует IFormattable интерфейс ToString() метод

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

вот пример.

// Define other methods and classes here
public class Sample : IFormattable
{
     public string ToString(string format, IFormatProvider provider)
     {
         return String.Concat("Your custom format was ", format);
     }
}

String.Format("{0:MyCustomFormat}", new Sample())
  1. Проверьте официальные документы MSDN, здесь есть полный список строк формата DateTime:http://msdn.microsoft.com/en-us/library/az4se3k1.aspx. действительно, существует довольно много "магических" струн.

  2. насколько я знаю, не все типы имеют "интересное" форматирование, но все типы поддерживают ToString(). Если вам нужно отформатировать встроенный объект, вы можете добавить метод расширения для этого, но обычно форматирование осуществляется в любое место, где это необходимо (или, говоря по-другому, я написал только пользовательские форматеры для своих собственных типов).

  3. Да, вы можете написать свой собственный, и если у вас есть данные, которые могут быть отформатированы по-разному, вы, вероятно, должны написать пользовательский форматер, реализовав IFormattable, снова см. документы здесь:http://msdn.microsoft.com/en-us/library/system.iformattable.aspx. это довольно просто, вы просто проверяете предоставленные строки и записываете свои данные исходя из этого, нет никакой магии за кулисами: -)

- под крышки строку.Формат делает что-то так:

IFormattable formattable = objectToFormat as IFormattable;
if (formattable != null)
{
    formattable.ToString(objectToFormat);
}
else
{
    objectToFormat.ToString();
}

на ваши вопросы,

  1. как строку.Формат сопоставьте дополнительную информацию MM/dd / yyyy со строковым результатом?

    как указано выше, он просто вызывает IFormattable .ToString (формат строки, поставщик IFormatProvider). Поставщик часто что-то, что говорит вам, что культура вашей системы. Часто null, потому что люди не проходят его Строка.Формат () как и в вашем случае.

  2. все ли объекты microsoft поддерживают эту функцию? Это где-то задокументировано?

    все, что реализует IFormattable делает.

  3. можно ли сделать что-то вроде этого: String.Format("{0:MyCustomFormat}, new MyOwnClass())

    по существу, если вы хотите, чтобы ваш собственный объект что-то делал с форматом, который вы реализуете IFormattable.

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

Да, это возможно - его можно полностью настроить. Посмотри на этой ссылка на документацию по пользовательскому форматированию даты и времени.

Если у вас есть свой собственный объект, это до вас, чтобы переопределить ToString() метод и выводите все, что вы считаете подходящим представлением. После этого вы можете использовать String.Format("{0:MyCustomFormat}", new MyOwnClass()) потому что это неявно называет MyOwnClass.ToString()

документация по датам можно найти здесь: http://msdn.microsoft.com/en-us/library/8kb3ddd4.aspx

что должен сказать вам точно, что все даты форматирование символов как мм означать.

Если вы хотите изменить способ вывода строки для пользовательского класса, вы можете переопределить метод ToString, например:

public class User
{
     public string Name { get; set; }
     public int Age { get; set; }

     public override string ToString()
     {
         return this.Name + " is " + this.Age + " years old.";
     }
}

и затем вы можете просто сделать что-то вроде myUser.ToString() и получить выход, который вы указали.

и чтобы ответить на ваш третий вопрос: это невозможно с помощью этого синтаксиса, но вы можете предоставить экземпляры IFormatProvider и ICustomFormatter для типа, который вы не создали или не реализовали IFormattable внутри вашего типа (хотя, что в основном распространяется ToString).