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

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

 

Опубликовано: Октябрь 2016

Форматирование — это процесс преобразования экземпляра класса, структуры или значения перечисления в строковое представление. Результирующая строка затем демонстрируется пользователям или десериализуется для последующего восстановления значения с исходным типом данных. Преобразование может быть связано с рядом проблем:

  • Внутреннее представление значений необязательно соответствует тому виду, в котором они должны быть представлены пользователям. Например, номер телефона может храниться в форме 8009999999, которая не отличается удобством для пользователей. Вместо этого номер должен отображаться в следующем виде: 800-999-9999. См. в подразделе Строки настраиваемого формата пример, в котором число форматируется таким образом.

  • Иногда порядок преобразования объекта в строковое представление неочевиден. Например, неясно, как должно выглядеть строковое представление объекта класса Temperature, представляющего температурные значения, или класса Person, представляющего данные о людях. Пример, в котором объект Temperature форматируется различными способами, см. в подразделе Строки стандартного формата.

  • Для некоторых значений может потребоваться форматирование, учитывающее язык и региональные параметры. Например, в приложении, где числа используются для обозначения денежных сумм, числовые строки должны включать символ текущей валюты, разделители групп (в большинстве случаев они совпадают с разделителями тысяч) и символ-разделитель целой и дробной частей. Пример см. в подразделе Форматирование с учетом языка и региональных параметров с помощью поставщиков формата и интерфейса IFormatProvider.

  • Одно и то же значение может быть необходимо представить в приложении несколькими способами. Например, приложение может представлять элемент перечисления, отображая строковое представление его имени или его базовое значение. Пример, в котором член перечисления DayOfWeek форматируется различными способами, см в подразделе Строки стандартного формата.

System_CAPS_noteПримечание

Форматирование приводит к преобразованию значения определенного типа в его строковое представление. Обратной по отношению к форматированию операцией является анализ. В ходе анализа на основании строкового представления создается экземпляр некоторого типа данных. Дополнительные сведения о преобразовании строк в другие типы данных см. в разделе Анализ строк в .NET Framework.

Платформа .NET Framework обеспечивает обширную поддержку форматирования, позволяя разработчикам справиться с описанными проблемами.

Обзор включает следующие разделы.

Базовый механизм форматирования — это используемая по умолчанию реализация метода Object.ToString, описанная ниже в подразделе Форматирование по умолчанию с помощью метода ToString. При этом платформа .NET Framework предоставляет несколько способов изменения и расширения имеющихся по умолчанию возможностей форматирования. , включая следующие основные параметры:

  • Переопределение метода Object.ToString, позволяющее определить настраиваемое строковое представление значения объекта. Дополнительные сведения см. ниже в подразделе Переопределение метода ToString.

  • Определение описателей формата, позволяющих использовать несколько видов строкового представления значения объекта. Например, описатель формата "X" в следующем операторе позволяет преобразовать целое число в шестнадцатеричное строковое представление.

    int integerValue = 60312;
    Console.WriteLine(integerValue.ToString("X"));   // Displays EB98.
    

    Дополнительные сведения об описателях форматов см. в подразделе Метод ToString и строки формата.

  • Использование поставщиков форматирования, позволяющих воспользоваться преимуществами соглашений о форматировании, присущих конкретному языку и региональным параметрам. Например, следующий оператор выводит значение валюты с использованием соглашений о форматировании языка и региональных параметров "en-US".

    double cost = 1632.54; 
    Console.WriteLine(cost.ToString("C", 
                      new System.Globalization.CultureInfo("en-US")));   
    // The example displays the following output:
    //       $1,632.54
    

    Дополнительные сведения о форматировании с помощью поставщиков форматирования см. в подразделе Поставщики форматирования и интерфейс IFormatProvider.

  • Реализация интерфейса IFormattable, позволяющая преобразовывать строки с помощью класса Convert и использовать составное форматирование. Дополнительные сведения см. в подразделе Интерфейс IFormattable.

  • Использование составного форматирования, позволяющее внедрить строковую презентацию в состав более крупной строки. Дополнительные сведения см. в подразделе Составное форматирование.

  • Реализация интерфейсов ICustomFormatter и IFormatProvider, позволяющая создать полноценное настраиваемое решение для форматирования. Дополнительные сведения см. в подразделе Настраиваемое форматирование с использованием интерфейса ICustomFormatter.

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

К началу

Любой производный от System.Object тип автоматически наследует метод ToString без параметров, по умолчанию возвращающий имя типа. В следующем примере демонстрируется использование метода ToString по умолчанию. Здесь определен класс с именем Automobile, у которого нет реализации. При создании экземпляра этого класса и вызове его метода ToString отображается имя класса. Обратите внимание, что метод ToString не вызывается в примере явным образом. Метод Console.WriteLine(Object) неявно вызывает метод ToString объекта, переданного ему в качестве аргумента.

using System;

public class Automobile
{
   // No implementation. All members are inherited from Object.
}

public class Example
{
   public static void Main()
   {
      Automobile firstAuto = new Automobile();
      Console.WriteLine(firstAuto);
   }
}
// The example displays the following output:
//       Automobile
System_CAPS_warningПредупреждение

Начиная с Windows 8.1Среда выполнения Windows включает интерфейс IStringable с единственным методом IStringable.ToString, который обеспечивает поддержку форматирования по умолчанию. Однако рекомендуется, чтобы управляемые типы не реализовывали интерфейс IStringable. Дополнительные сведения см. в подразделе "Среда выполнения Windows и интерфейс IStringable" справочных сведений о методе Object.ToString.

Поскольку производными от Object являются все типы, кроме интерфейсов, данная функциональность автоматически присутствует в пользовательских классах и структурах. Тем не менее метод ToString по умолчанию обладает весьма ограниченной функциональностью: хотя метод позволяет определить имя типа, никаких сведений об экземпляре типа он не предоставляет. Для формирования строкового представления объекта, позволяющего получить сведения о конкретном объекте, следует переопределить метод ToString.

System_CAPS_noteПримечание

Структуры наследуют от типа ValueType, который также является наследником Object. Хотя в ValueType метод Object.ToString переопределен, его реализация идентична базовой.

К началу

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

using System;

public class Temperature
{
   private decimal temp;

   public Temperature(decimal temperature)
   {
      this.temp = temperature;   
   }

   public override string ToString()
   {
      return this.temp.ToString("N1") + "°C";
   }
}

public class Example
{
   public static void Main()
   {
      Temperature currentTemperature = new Temperature(23.6m);
      Console.WriteLine("The current temperature is " +
                        currentTemperature.ToString());
   }
}
// The example displays the following output:
//       The current temperature is 23.6°C.

В платформе .NET Framework метод ToString переопределен у всех типов-примитивов значений: вместо имени он отображает значение объекта. В следующей таблице показаны переопределения для всех типов-примитивов. Обратите внимание, что большинство переопределенных методов вызывают другую перегрузку метода ToString и передают ей описатель формата "G", который задает общий формат типа, и объект IFormatProvider, представляющий текущий язык и региональные параметры.

Тип

Переопределение ToString

Boolean

Возвращает Boolean.TrueString или Boolean.FalseString.

Byte

Вызывает метод Byte.ToString("G", NumberFormatInfo.CurrentInfo), чтобы отформатировать значение Byte в соответствии с текущим языком и региональными параметрами.

Char

Возвращает символ в виде строки.

DateTime

Вызывает метод DateTime.ToString("G", DatetimeFormatInfo.CurrentInfo), чтобы отформатировать значение даты и времени в соответствии с текущим языком и региональными параметрами.

Decimal

Вызывает метод Decimal.ToString("G", NumberFormatInfo.CurrentInfo), чтобы отформатировать значение Decimal в соответствии с текущим языком и региональными параметрами.

Double

Вызывает метод Double.ToString("G", NumberFormatInfo.CurrentInfo), чтобы отформатировать значение Double в соответствии с текущим языком и региональными параметрами.

Int16

Вызывает метод Int16.ToString("G", NumberFormatInfo.CurrentInfo), чтобы отформатировать значение Int16 в соответствии с текущим языком и региональными параметрами.

Int32

Вызывает метод Int32.ToString("G", NumberFormatInfo.CurrentInfo), чтобы отформатировать значение Int32 в соответствии с текущим языком и региональными параметрами.

Int64

Вызывает метод Int64.ToString("G", NumberFormatInfo.CurrentInfo), чтобы отформатировать значение Int64 в соответствии с текущим языком и региональными параметрами.

SByte

Вызывает метод SByte.ToString("G", NumberFormatInfo.CurrentInfo), чтобы отформатировать значение SByte в соответствии с текущим языком и региональными параметрами.

Single

Вызывает метод Single.ToString("G", NumberFormatInfo.CurrentInfo), чтобы отформатировать значение Single в соответствии с текущим языком и региональными параметрами.

UInt16

Вызывает метод UInt16.ToString("G", NumberFormatInfo.CurrentInfo), чтобы отформатировать значение UInt16 в соответствии с текущим языком и региональными параметрами.

UInt32

Вызывает метод UInt32.ToString("G", NumberFormatInfo.CurrentInfo), чтобы отформатировать значение UInt32 в соответствии с текущим языком и региональными параметрами.

UInt64

Вызывает метод UInt64.ToString("G", NumberFormatInfo.CurrentInfo), чтобы отформатировать значение UInt64 в соответствии с текущим языком и региональными параметрами.

К началу

Использовать метод ToString по умолчанию или перегрузку ToString удобно, если у объекта имеется однозначное строковое представление. Тем не менее зачастую значение объекта может иметь несколько представлений. Например, температура может выражаться в градусах по шкале Фаренгейта, Цельсия или Кельвина. Аналогично, целое число 10 можно представить различными способами, включая 10, 10.0, 1.0e01 или $10.00.

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

Все числовые типы, типы даты и времени, а также перечисления в составе платформы .NET Framework поддерживают предопределенный набор описателей формата. Строки формата также можно использовать для определения разнообразных строковых представлений прикладных пользовательских типов данных.

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

В платформе .NET Framework определяется набор описателей стандартного формата для всех числовых типов, типов даты и времени, а также для всех типов перечислений. Например, все эти категории поддерживают описатель стандартного формата "G", который определяет общее строковое представление значения соответствующего типа.

Строки стандартного формата для типов перечислений напрямую определяют строковое представление значения. От строки формата, переданной в метод ToString значения перечисления, зависит, будет оно представлено своим строковым именем (описатели формата "G" и "F"), базовым целочисленным значением (описатель формата "D") или шестнадцатеричным значением (описатель формата "X"). В следующем примере демонстрируется использование строк стандартного формата для форматирования значения перечисления DayOfWeek.

DayOfWeek thisDay = DayOfWeek.Monday;
string[] formatStrings = {"G", "F", "D", "X"};

foreach (string formatString in formatStrings)
   Console.WriteLine(thisDay.ToString(formatString));
// The example displays the following output:
//       Monday
//       Monday
//       1
//       00000001

Сведения о строках форматов перечислений см. в разделе Строки форматов перечисления.

Строки стандартного формата для числовых типов обычно задают результирующую строку, точный вид которой зависит от значения одного или нескольких свойств. Например, описатель формата "C" форматирует число в виде значения валюты. При вызове метода ToString с описателем формата "C" в качестве единственного параметра для определения строкового представления числового значения используются следующие свойства объекта NumberFormatInfo для текущего языка и региональных параметров:

  • Свойство CurrencySymbol, определяющее символ валюты для текущего языка и региональных параметров.

  • Свойство CurrencyNegativePattern или CurrencyPositivePattern, возвращающее целое число, от которого зависит следующее:

    • Положение символа валюты.

    • Обозначение отрицательных значений: отрицательный знак в начале, отрицательный знак в конце или круглые скобки.

    • Наличие пробела между числовым значением и символом валюты.

  • Свойство CurrencyDecimalDigits, определяющее число цифр дробной части в результирующей строке.

  • Свойство CurrencyDecimalSeparator, определяющее символ-разделитель целой и дробной частей в результирующей строке.

  • Свойство CurrencyGroupSeparator, определяющее символ-разделитель групп.

  • Свойство CurrencyGroupSizes, определяющее число цифр в каждой из групп слева от разделителя целой и дробной частей.

  • Свойство NegativeSign, задающее отрицательный знак, который используется в случаях, если скобки не применяются для обозначения отрицательных значений в результирующей строке.

Кроме того, строки числового формата могут содержать описатель точности. Смысл этого описателя зависит от строки формата, в которой он используется, но обычно он задает общее число цифр в результирующей строке или число цифр в дробной части. В следующем примере используется строка стандартного числового формата с описателем точности ("X4"), что позволяет сформировать строковое значение из четырех шестнадцатеричных цифр.

byte[] byteValues = { 12, 163, 255 };
foreach (byte byteValue in byteValues)
   Console.WriteLine(byteValue.ToString("X4"));
// The example displays the following output:
//       000C
//       00A3
//       00FF

Дополнительные сведения о строках стандартных числовых форматов см. в разделе Строки стандартных числовых форматов.

Строки стандартного формата для значений даты и времени — это псевдонимы строк настраиваемого формата, которые хранятся в конкретном свойстве DateTimeFormatInfo. Например, вызов метода ToString применительно к значению даты и времени с описателем формата "D" приведет к отображению даты и времени с помощью настраиваемой строки формата, хранящейся в свойстве DateTimeFormatInfo.LongDatePattern для текущего языка и региональных параметров. (Дополнительные сведения о строках настраиваемого формата см. в следующем подразделе.) Данная связь показана в следующем примере.

using System;
using System.Globalization;

public class Example
{
   public static void Main()
   {
      DateTime date1 = new DateTime(2009, 6, 30);
      Console.WriteLine("D Format Specifier:     {0:D}", date1);
      string longPattern = CultureInfo.CurrentCulture.DateTimeFormat.LongDatePattern;
      Console.WriteLine("'{0}' custom format string:     {1}", 
                        longPattern, date1.ToString(longPattern));
   }
}
// The example displays the following output when run on a system whose
// current culture is en-US:
//    D Format Specifier:     Tuesday, June 30, 2009
//    'dddd, MMMM dd, yyyy' custom format string:     Tuesday, June 30, 2009

Дополнительные сведения о строках стандартных форматов даты и времени см. в разделе Строки стандартных форматов даты и времени.

Строки стандартного формата также можно использовать для определения строкового представления прикладного объекта, формируемого с помощью метода ToString(String) такого объекта. Можно определить конкретные описатели стандартного формата, поддерживаемые объектом, а также решить, будут ли они зависеть от регистра символов. Реализация метода ToString(String) должна отвечать следующим условиям:

  • Должен поддерживаться описатель формата "G", отвечающий за представление обычного или общего формата объекта. Перегрузка метода ToString объекта, не имеющая параметров, должна вызывать его перегрузку ToString(String), передавая ей строку стандартного формата "G".

  • Должен поддерживаться описатель формата, равный пустой ссылке (Nothing в Visual Basic). Описатель формата, равный пустой ссылке, должен рассматриваться как эквивалент описателя формата "G".

Например, во внутреннем представлении класса Temperature температура может храниться в градусах Цельсия, а для представления значения объекта Temperature в градусах Цельсия, Фаренгейта или Кельвина могут использоваться различные описатели формата. Ниже приведен пример.

using System;

public class Temperature
{
   private decimal m_Temp;

   public Temperature(decimal temperature)
   {
      this.m_Temp = temperature;
   }

   public decimal Celsius
   {
      get { return this.m_Temp; }
   }

   public decimal Kelvin
   {
      get { return this.m_Temp + 273.15m; }   
   }

   public decimal Fahrenheit
   {
      get { return Math.Round(((decimal) (this.m_Temp * 9 / 5 + 32)), 2); }
   }

   public override string ToString()
   {
      return this.ToString("C");
   }

   public string ToString(string format)
   {  
      // Handle null or empty string.
      if (String.IsNullOrEmpty(format)) format = "C";
      // Remove spaces and convert to uppercase.
      format = format.Trim().ToUpperInvariant();      

      // Convert temperature to Fahrenheit and return string.
      switch (format)
      {
         // Convert temperature to Fahrenheit and return string.
         case "F":
            return this.Fahrenheit.ToString("N2") + " °F";
         // Convert temperature to Kelvin and return string.
         case "K":
            return this.Kelvin.ToString("N2") + " K";
         // return temperature in Celsius.
         case "G":
         case "C":
            return this.Celsius.ToString("N2") + " °C";
         default:
            throw new FormatException(String.Format("The '{0}' format string is not supported.", format));
      }      
   }
}

public class Example
{
   public static void Main()
   {
      Temperature temp1 = new Temperature(0m);
      Console.WriteLine(temp1.ToString());
      Console.WriteLine(temp1.ToString("G"));
      Console.WriteLine(temp1.ToString("C"));
      Console.WriteLine(temp1.ToString("F"));
      Console.WriteLine(temp1.ToString("K"));

      Temperature temp2 = new Temperature(-40m);
      Console.WriteLine(temp2.ToString());
      Console.WriteLine(temp2.ToString("G"));
      Console.WriteLine(temp2.ToString("C"));
      Console.WriteLine(temp2.ToString("F"));
      Console.WriteLine(temp2.ToString("K"));

      Temperature temp3 = new Temperature(16m);
      Console.WriteLine(temp3.ToString());
      Console.WriteLine(temp3.ToString("G"));
      Console.WriteLine(temp3.ToString("C"));
      Console.WriteLine(temp3.ToString("F"));
      Console.WriteLine(temp3.ToString("K"));

      Console.WriteLine(String.Format("The temperature is now {0:F}.", temp3));
   }
}
// The example displays the following output:
//       0.00 °C
//       0.00 °C
//       0.00 °C
//       32.00 °F
//       273.15 K
//       -40.00 °C
//       -40.00 °C
//       -40.00 °C
//       -40.00 °F
//       233.15 K
//       16.00 °C
//       16.00 °C
//       16.00 °C
//       60.80 °F
//       289.15 K
//       The temperature is now 16.00 °C.

К началу

Помимо строк стандартного формата, в платформе .NET Framework для числовых значений и значений даты и времени определяются строки настраиваемого формата. Строка настраиваемого формата состоит из одного или нескольких описателей настраиваемого формата, описывающих строковое представление значения. Например, строка настраиваемого формата даты и времени, заданная как "yyyy/mm/dd hh:mm:ss.ffff t zzz", преобразует дату в строковое представления вида "2008/11/15 07:45:00.0000 P -08:00" для языка и региональных параметров "en-US". Аналогично строка настраиваемого формата "0000" приведет к преобразованию целочисленного значения 12 в строку "0012". Полный список строк настраиваемого формата см. в разделах Строки настраиваемых форматов даты и времени и Строки настраиваемых числовых форматов.

Если строка формата состоит из одного описателя настраиваемого формата, то перед ним должен стоять символ процента (%), чтобы его можно было отличить от описателя стандартного формата. В следующем примере описатель настраиваемого формата "М" используется для вывода одно- или двухзначного числа месяца для определенной даты.

DateTime date1 = new DateTime(2009, 9, 8);
Console.WriteLine(date1.ToString("%M"));       // Displays 9

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

string customFormat = "MMMM dd, yyyy (dddd)";
DateTime date1 = new DateTime(2009, 8, 28);
Console.WriteLine(date1.ToString(customFormat));   
// The example displays the following output if run on a system
// whose language is English:
//       August 28, 2009 (Friday)      

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

using System;

public class Example
{
   public static void Main()
   {
      long number = 8009999999;
      string fmt = "000-000-0000";
      Console.WriteLine(number.ToString(fmt));
   }
}
// The example displays the following output:
//        800-999-9999

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

К началу

Все числовые типы (то есть Byte, Decimal, Double, Int16, Int32, Int64, SByte, Single, UInt16, UInt32, UInt64 и BigInteger),

а также DateTime, DateTimeOffset, TimeSpan, Guid и все типы перечислений поддерживают форматирование с помощью строк форматов. Сведения о конкретных строках форматов, поддерживаемых каждым типом, см. в следующих разделах.

Название

Определение

Строки стандартных числовых форматов

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

Строки настраиваемых числовых форматов

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

Строки стандартных форматов даты и времени

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

Строки настраиваемых форматов даты и времени

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

Строки стандартного формата TimeSpan

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

Строки пользовательского формата TimeSpan

Описание строк настраиваемого формата, позволяющих создавать прикладные строковые представления интервалов времени.

Строки форматов перечисления

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

Guid.ToString(String)

Описание строк стандартного формата для значений Guid.

Хотя описатели формата позволяют настраивать форматирование объектов, для формирования осмысленного строкового представления объектов зачастую требуется дополнительная информация, связанная с форматированием. Например, при форматировании числового значения в формате валюты с помощью строки стандартного формата "C" или строки настраиваемого формата "$ #,#.00" для включения в отформатированную строку должен быть известен нужный символ валюты, разделитель групп, а также разделитель целой и дробной частей. В платформе .NET Framework подобные дополнительные сведения предоставляются с помощью интерфейса IFormatProvider, передаваемого в качестве параметра одной или нескольких перегрузок метода ToString для числовых типов и типов даты и времени. Реализации IFormatProvider используются в .NET Framework для поддержки форматирования с учетом языка и региональных параметров. В следующем примере показано, как меняется строковое представление объекта при его форматировании с использованием трех разных объектов IFormatProvider.

using System;
using System.Globalization;

public class Example
{
   public static void Main()
   {
      decimal value = 1603.42m;
      Console.WriteLine(value.ToString("C3", new CultureInfo("en-US")));
      Console.WriteLine(value.ToString("C3", new CultureInfo("fr-FR")));
      Console.WriteLine(value.ToString("C3", new CultureInfo("de-DE")));
   }
}
// The example displays the following output:
//       $1,603.420
//       1 603,420 €
//       1.603,420 €

Интерфейс IFormatProvider включает один метод, GetFormat(Type), имеющий один параметр, задающий тип объекта, предоставляющего сведения о форматировании. Если метод может предоставить объект указанного типа, то он его возвращает. В противном случае метод возвратит пустую ссылку (Nothing в Visual Basic).

Метод IFormatProvider.GetFormat является методом обратного вызова. При вызове перегрузки метода ToString, имеющей параметр IFormatProvider, вызывается метод GetFormat соответствующего объекта IFormatProvider. Метод GetFormat должен вернуть в метод formatType объект, способный предоставить необходимые сведения о форматировании и соответствующий параметру ToString.

Многие методы форматирования и преобразования строк имеют параметр типа IFormatProvider, но во многих случаях значение параметра игнорируется при вызове метода. В следующей таблице перечислены некоторые методы форматирования, использующие этот параметр. Для каждого метода также указывается тип объекта Type, передаваемого в метод IFormatProvider.GetFormat.

Метод

Тип параметра formatType

Метод ToString для числовых типов

System.Globalization.NumberFormatInfo

Метод ToString для типов даты и времени

System.Globalization.DateTimeFormatInfo

String.Format

System.ICustomFormatter

StringBuilder.AppendFormat

System.ICustomFormatter

System_CAPS_noteПримечание

Методы ToString у числовых типов и типов даты и времени перегружены; параметр IFormatProvider имеется лишь у некоторых перегрузок. Если у метода нет параметра типа IFormatProvider, то вместо этого передается объект, возвращаемый свойством CultureInfo.CurrentCulture. Например, вызов метода Int32.ToString() по умолчанию в итоге приведет к подобному вызову метода: Int32.ToString("G", System.Globalization.CultureInfo.CurrentCulture).

В составе платформы .NET Framework есть три класса, реализующих интерфейс IFormatProvider.

  • DateTimeFormatInfo: класс, предоставляющий сведения о форматировании значений даты и времени для конкретного языка и региональных параметров. Реализация метода IFormatProvider.GetFormat в этом классе возвращает его экземпляр.

  • NumberFormatInfo: класс, предоставляющий сведения о форматировании числовых значений для конкретного языка и региональных параметров. Реализация метода IFormatProvider.GetFormat в этом классе возвращает его экземпляр.

  • CultureInfo. Реализация метода IFormatProvider.GetFormat в этом классе возвращает объект NumberFormatInfo, предоставляющий сведения о форматировании числовых значений, либо объект DateTimeFormatInfo, предоставляющий сведения о форматировании значений даты и времени.

Также можно реализовать пользовательский поставщик форматирования, позволяющий заменить любой из этих классов. При этом пользовательская реализация метода GetFormat, рассчитанная на предоставление сведений о форматировании для метода ToString, должна возвращать объект одного из типов, перечисленных в приведенной выше таблице.

К началу

По умолчанию форматирование числовых значений зависит от языка и региональных параметров. Если не указать язык и региональные параметры при вызове метода форматирования, используются соглашения о форматировании текущего языка и региональных параметров. Это продемонстрировано в следующем примере, который изменяет текущие язык и региональные параметры четыре раза, а затем вызывает метод Decimal.ToString(String). В каждом случае результирующая строка отражает соглашения о форматировании текущих языка и региональных параметров. Это происходит потому, что методы ToString и ToString(String) создают оболочки для вызовов метода ToString(String, IFormatProvider) каждого числового типа.

using System;
using System.Globalization;
using System.Threading;

public class Example
{
   public static void Main()
   {
      string[] cultureNames = { "en-US", "fr-FR", "es-MX", "de-DE" };
      Decimal value = 1043.17m;

      foreach (var cultureName in cultureNames) {
         // Change the current thread culture.
         Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture(cultureName);
         Console.WriteLine("The current culture is {0}", 
                           Thread.CurrentThread.CurrentCulture.Name);
         Console.WriteLine(value.ToString("C2"));
         Console.WriteLine();
      }   
   }
}
// The example displays the following output:
//       The current culture is en-US
//       $1,043.17
//       
//       The current culture is fr-FR
//       1 043,17 €
//       
//       The current culture is es-MX
//       $1,043.17
//       
//       The current culture is de-DE
//       1.043,17 €

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

  • объекта CultureInfo, представляющего язык и региональные параметры, соглашения о форматировании которых требуется использовать. Его метод CultureInfo.GetFormat возвращает значение свойства CultureInfo.NumberFormat, которое является объектом NumberFormatInfo, предоставляющим сведения о форматировании в соответствии с языком и региональными параметрами для числовых значений;

  • объекта NumberFormatInfo, определяющего соглашения о форматировании для используемых языка и региональных параметров. Метод GetFormat этого класса возвращает экземпляр его самого.

В следующем примере объекты NumberFormatInfo, представляющие "Английский (США)" и "Английский (Великобритания)" язык и региональные параметры, а также "Французский" и "Русский" нейтральные языки и региональные параметры, используются для форматирования числа с плавающей запятой.

using System;
using System.Globalization;

public class Example
{
   public static void Main()
   {                                                                                                    
      Double value = 1043.62957;
      string[] cultureNames = { "en-US", "en-GB", "ru", "fr" };

      foreach (var name in cultureNames) {
         NumberFormatInfo nfi = CultureInfo.CreateSpecificCulture(name).NumberFormat;
         Console.WriteLine("{0,-6} {1}", name + ":", value.ToString("N3", nfi));
      }   
   }
}
// The example displays the following output:
//       en-US: 1,043.630
//       en-GB: 1,043.630
//       ru:    1 043,630
//       fr:    1 043,630

По умолчанию форматирование значений даты и времени зависит от языка и региональных параметров. Если не указать язык и региональные параметры при вызове метода форматирования, используются соглашения о форматировании текущего языка и региональных параметров. Это продемонстрировано в следующем примере, который изменяет текущие язык и региональные параметры четыре раза, а затем вызывает метод DateTime.ToString(String). В каждом случае результирующая строка отражает соглашения о форматировании текущих языка и региональных параметров. Это происходит потому, что методы DateTime.ToString(), DateTime.ToString(String), DateTimeOffset.ToString() и DateTimeOffset.ToString(String) создают оболочки для вызовов методов DateTime.ToString(String, IFormatProvider) и DateTimeOffset.ToString(String, IFormatProvider).

using System;
using System.Globalization;
using System.Threading;

public class Example
{
   public static void Main()
   {
      string[] cultureNames = { "en-US", "fr-FR", "es-MX", "de-DE" };
      DateTime dateToFormat = new DateTime(2012, 5, 28, 11, 30, 0);

      foreach (var cultureName in cultureNames) {
         // Change the current thread culture.
         Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture(cultureName);
         Console.WriteLine("The current culture is {0}", 
                           Thread.CurrentThread.CurrentCulture.Name);
         Console.WriteLine(dateToFormat.ToString("F"));
         Console.WriteLine();
      }   
   }
}
// The example displays the following output:
//       The current culture is en-US
//       Monday, May 28, 2012 11:30:00 AM
//       
//       The current culture is fr-FR
//       lundi 28 mai 2012 11:30:00
//       
//       The current culture is es-MX
//       lunes, 28 de mayo de 2012 11:30:00 a.m.
//       
//       The current culture is de-DE
//       Montag, 28. Mai 2012 11:30:00

Форматировать значения даты и времени для определенных языка и региональных параметров также можно путем вызова перегрузки методов DateTime.ToString или DateTimeOffset.ToString, которая имеет параметр provider, и передачи ей одного из следующих объектов:

  • объекта CultureInfo, представляющего язык и региональные параметры, соглашения о форматировании которых требуется использовать. Его метод CultureInfo.GetFormat возвращает значение свойства CultureInfo.DateTimeFormat, которое является объектом DateTimeFormatInfo, предоставляющим сведения о форматировании в соответствии с языком и региональными параметрами для значений даты и времени;

  • объекта DateTimeFormatInfo, определяющего соглашения о форматировании для используемых языка и региональных параметров. Метод GetFormat этого класса возвращает экземпляр его самого.

В следующем примере объекты DateTimeFormatInfo, представляющие "Английский (США)" и "Английский (Великобритания)" язык и региональные параметры, а также "Французский" и "Русский" нейтральные языки и региональные параметры, используются для форматирования даты.

using System;
using System.Globalization;

public class Example
{
   public static void Main()
   {                                                                                                    
      DateTime dat1 = new DateTime(2012, 5, 28, 11, 30, 0);
      string[] cultureNames = { "en-US", "en-GB", "ru", "fr" };

      foreach (var name in cultureNames) {
         DateTimeFormatInfo dtfi = CultureInfo.CreateSpecificCulture(name).DateTimeFormat;
         Console.WriteLine("{0}: {1}", name, dat1.ToString(dtfi));
      }   
   }
}
// The example displays the following output:
//       en-US: 5/28/2012 11:30:00 AM
//       en-GB: 28/05/2012 11:30:00
//       ru: 28.05.2012 11:30:00
//       fr: 28/05/2012 11:30:00

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

Реализация интерфейса IFormattable в прикладных типах позволяет получить два преимущества:

  • Поддержка строковых преобразований с помощью класса Convert. При вызове методов Convert.ToString(Object) и Convert.ToString(Object, IFormatProvider) автоматически вызывается пользовательская реализация IFormattable.

  • Поддержка составного форматирования. Если для форматирования пользовательского типа используется элемент форматирования, включающий строку формата, то среда CLR автоматически вызывает пользовательскую реализацию IFormattable, передавая ей строку формата. Дополнительные сведения о составном форматировании с помощью таких методов, как String.Format или Console.WriteLine, см. в подразделе Составное форматирование.

В следующем примере определяется класс Temperature, реализующий интерфейс IFormattable. Он поддерживает описатели формата "C" и "G", позволяющие отобразить значение температуры в градусах Цельсия, описатель формата "F", позволяющий отобразить значение температуры в градусах Фаренгейта, и описатель формата "K", позволяющий отобразить значение температуры в градусах Кельвина.

using System;
using System.Globalization;

public class Temperature : IFormattable
{
   private decimal m_Temp;

   public Temperature(decimal temperature)
   {
      this.m_Temp = temperature;
   }

   public decimal Celsius
   {
      get { return this.m_Temp; }
   }

   public decimal Kelvin
   {
      get { return this.m_Temp + 273.15m; }   
   }

   public decimal Fahrenheit
   {
      get { return Math.Round((decimal) this.m_Temp * 9 / 5 + 32, 2); }
   }

   public override string ToString()
   {
      return this.ToString("G", null);
   }

   public string ToString(string format)
   {
      return this.ToString(format, null);
   }

   public string ToString(string format, IFormatProvider provider)  
   {
      // Handle null or empty arguments.
      if (String.IsNullOrEmpty(format)) format = "G";
      // Remove any white space and convert to uppercase.
      format = format.Trim().ToUpperInvariant();

      if (provider == null) provider = NumberFormatInfo.CurrentInfo;

      switch (format)
      {
         // Convert temperature to Fahrenheit and return string.
         case "F":
            return this.Fahrenheit.ToString("N2", provider) + "°F";
         // Convert temperature to Kelvin and return string.
         case "K":
            return this.Kelvin.ToString("N2", provider) + "K";
         // Return temperature in Celsius.
         case "C":
         case "G":
            return this.Celsius.ToString("N2", provider) + "°C";
         default:
            throw new FormatException(String.Format("The '{0}' format string is not supported.", format));
      }      
   }
}

В следующем примере создается объект Temperature. Затем в нем вызывается метод ToString. Использование нескольких строк составного формата позволяет получить различные строковые представления объекта Temperature. В свою очередь каждый из этих вызовов метода вызывает реализацию IFormattable класса Temperature.

public class Example
{
   public static void Main()
   {
      Temperature temp1 = new Temperature(22m);
      Console.WriteLine(Convert.ToString(temp1, new CultureInfo("ja-JP")));
      Console.WriteLine("Temperature: {0:K}", temp1);
      Console.WriteLine("Temperature: {0:F}", temp1);
      Console.WriteLine(String.Format(new CultureInfo("fr-FR"), "Temperature: {0:F}", temp1));
   }
}
// The example displays the following output:
//       22.00°C
//       Temperature: 295.15°K
//       Temperature: 71.60°F
//       Temperature: 71,60°F

К началу

Некоторые методы, например String.Format и StringBuilder.AppendFormat, поддерживают составное форматирование. Строка составного формата — это некий шаблон, возвращающий единую строку, включающую строковое представление нулевого, единичного или другого числа объектов. Каждый объект представляется в строке составного формата индексированным элементом форматирования. Индекс элемента форматирования соответствует положению представляющего его объекта в списке параметров метода. Индексы отсчитываются от нуля. Например, в вызове метода String.Format первый элемент форматирования, {0:D}, замещается строковым представлением thatDate; второй элемент форматирования, {1}, замещается строковым представлением item1; а третий элемент форматирования, {2:C2}, замещается строковым представлением item1.Value.

result = String.Format("On {0:d}, the inventory of {1} was worth {2:C2}.", 
                       thatDate, item1, item1.Value);
Console.WriteLine(result);                            
// The example displays output like the following if run on a system
// whose current culture is en-US:
//       On 5/1/2009, the inventory of WidgetA was worth $107.44.

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

  • Вы можете указать конкретный способ представления объекта в виде строки, если объект реализует интерфейс IFormattable и поддерживает строки формата. Для этого после индекса элемента форматирования необходимо ввести : (двоеточие), а за ним — допустимую строку формата. В предыдущем примере для этого выполнялось форматирование значения даты с помощью строки формата "d" (шаблон короткого формата даты, например, {0:d}) и форматирование числового значения с помощью строки формата "C2" (например, {2:C2} для представления числа в виде значения валюты с двумя цифрами дробной части).

  • Вы можете задать ширину поля, содержащего строковое представление объекта, и выравнивание строкового представления в этом поле. Для этого после индекса элемента форматирования необходимо ввести , (запятую), а за ней — значение ширины поля. Строка выравнивается по правому краю поля, если ширина поля — положительное значение, и по левому краю, если ширина поля — отрицательное значение. В примере ниже значения даты выравниваются по левому краю поля из 20 символов, а десятичные значения с одной цифрой дробной части — по правом краю поля из 11 символов.

    DateTime startDate = new DateTime(2015, 8, 28, 6, 0, 0);
    decimal[] temps = { 73.452m, 68.98m, 72.6m, 69.24563m,
                       74.1m, 72.156m, 72.228m };
    Console.WriteLine("{0,-20} {1,11}\n", "Date", "Temperature");
    for (int ctr = 0; ctr < temps.Length; ctr++)
       Console.WriteLine("{0,-20:g} {1,11:N1}", startDate.AddDays(ctr), temps[ctr]);
    
    // The example displays the following output:
    //       Date                 Temperature
    //
    //       8/28/2015 6:00 AM           73.5
    //       8/29/2015 6:00 AM           69.0
    //       8/30/2015 6:00 AM           72.6
    //       8/31/2015 6:00 AM           69.2
    //       9/1/2015 6:00 AM            74.1
    //       9/2/2015 6:00 AM            72.2
    //       9/3/2015 6:00 AM            72.2
    

    Обратите внимание на то, что если присутствует и компонент выравнивания строки, и компонент строки формата, первый из них предшествует последнему (например, {0,-20:g}).

Дополнительные сведения о составном форматировании см. в разделе Составное форматирование.

К началу

У двух методов составного форматирования — String.Format(IFormatProvider, String, Object[]) и StringBuilder.AppendFormat(IFormatProvider, String, Object[]) — также имеется параметр, задающий поставщик форматирования, поддерживающий настраиваемое форматирование. При вызове какого-либо из этих методов форматирования объект Type, представляющий интерфейс ICustomFormatter, передается методу GetFormat поставщика форматирования. Метод GetFormat должен вернуть реализацию ICustomFormatter, поддерживающую настраиваемое форматирование.

Единственный метод интерфейса ICustomFormatter, который называется Format(String, Object, IFormatProvider), автоматически вызывается методом составного форматирования по одному разу для каждого элемента форматирования в строке составного формата. У метода Format(String, Object, IFormatProvider) есть три параметра: строка формата, представляющая аргумент formatString в элементе форматирования, сам форматируемый объект и объект IFormatProvider, предоставляющий услуги форматирования. Обычно класс, реализующий интерфейс ICustomFormatter, также реализует интерфейс IFormatProvider, поэтому в таком случае последний параметр будет ссылкой на сам класс настраиваемого форматирования. Метод возвращает настраиваемое строковое представление объекта, который нужно было отформатировать. Если методу не удается отформатировать объект, он должен вернуть пустую ссылку (Nothing в Visual Basic).

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

public class ByteByByteFormatter : IFormatProvider, ICustomFormatter
{
   public object GetFormat(Type formatType)
   { 
      if (formatType == typeof(ICustomFormatter))
         return this;
      else
         return null;
   }

   public string Format(string format, object arg, 
                          IFormatProvider formatProvider)
   {   
      if (! formatProvider.Equals(this)) return null;

      // Handle only hexadecimal format string.
      if (! format.StartsWith("X")) return null;

      byte[] bytes;
      string output = null;

      // Handle only integral types.
      if (arg is Byte) 
         bytes = BitConverter.GetBytes((Byte) arg);
      else if (arg is Int16)
         bytes = BitConverter.GetBytes((Int16) arg);
      else if (arg is Int32)
         bytes = BitConverter.GetBytes((Int32) arg);
      else if (arg is Int64)   
         bytes = BitConverter.GetBytes((Int64) arg);
      else if (arg is SByte)
         bytes = BitConverter.GetBytes((SByte) arg);
      else if (arg is UInt16)
         bytes = BitConverter.GetBytes((UInt16) arg);
      else if (arg is UInt32)
         bytes = BitConverter.GetBytes((UInt32) arg);
      else if (arg is UInt64)
         bytes = BitConverter.GetBytes((UInt64) arg);
      else
         return null;

      for (int ctr = bytes.Length - 1; ctr >= 0; ctr--)
         output += String.Format("{0:X2} ", bytes[ctr]);   

      return output.Trim();
   }
}

В следующем примере класс ByteByByteFormatter используется для форматирования целочисленных значений. Обратите внимание, что метод ICustomFormatter.Format вызывается во втором вызове метода String.Format(IFormatProvider, String, Object[]) несколько раз и что в третьем вызове метода используется поставщик NumberFormatInfo по умолчанию, поскольку метод ByteByByteFormatter.Format не распознает строку формата "N0" и возвращает пустую ссылку (Nothing в Visual Basic).

public class Example
{
   public static void Main()
   {
      long value = 3210662321; 
      byte value1 = 214;
      byte value2 = 19;

      Console.WriteLine(String.Format(new ByteByByteFormatter(), "{0:X}", value));
      Console.WriteLine(String.Format(new ByteByByteFormatter(), "{0:X} And {1:X} = {2:X} ({2:000})", 
                                      value1, value2, value1 & value2));                                
      Console.WriteLine(String.Format(new ByteByByteFormatter(), "{0,10:N0}", value));
   }
}
// The example displays the following output:
//       00 00 00 00 BF 5E D1 B1
//       00 D6 And 00 13 = 00 12 (018)
//       3,210,662,321

К началу

Название

Определение

Строки стандартных числовых форматов

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

Строки настраиваемых числовых форматов

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

Строки стандартных форматов даты и времени

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

Строки настраиваемых форматов даты и времени

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

Строки стандартного формата TimeSpan

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

Строки пользовательского формата TimeSpan

Описание строк настраиваемого формата, позволяющих создавать прикладные строковые представления интервалов времени.

Строки форматов перечисления

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

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

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

Выполнение операций форматирования

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

Анализ строк в .NET Framework

Описание способов инициализации объектов со значениями, описанными строковыми представлениями этих объектов. Разбор является операцией, обратной форматированию.

К началу

Показ: