Format 方法
TOC
折叠目录
展开目录
本文由机器翻译。若要查看英语原文,请勾选“英语”复选框。 也可将鼠标指针移到文本上,在弹出窗口中显示英语原文。
翻译
英语

String.Format 方法

 

将对象的值转换为基于指定格式的字符串,并将其插入到另一个字符串。

如果你不熟悉 String.Format 方法,请参阅 String.Format 方法入门一节来进行快速了解。

有关所有 String.Format 重载的完整文档,请参阅备注部分。

命名空间:   System
程序集:  mscorlib(mscorlib.dll 中)

名称说明
System_CAPS_pubmethodSystem_CAPS_staticFormat(IFormatProvider, String, Object)

将指定字符串中的一个或多个格式项替换为对应对象的字符串表示形式。 参数提供区域性特定的格式设置信息。

System_CAPS_pubmethodSystem_CAPS_staticFormat(IFormatProvider, String, Object, Object)

将指定字符串中的格式项替换为两个指定对象的字符串表示形式。 参数提供区域性特定的格式设置信息。

System_CAPS_pubmethodSystem_CAPS_staticFormat(IFormatProvider, String, Object, Object, Object)

将指定字符串中的格式项替换为三个指定对象的字符串表示形式。 参数提供区域性特定的格式设置信息。

System_CAPS_pubmethodSystem_CAPS_staticFormat(IFormatProvider, String, Object[])

将指定字符串中的格式项替换为指定数组中相应对象的字符串表示形式。 参数提供区域性特定的格式设置信息。

System_CAPS_pubmethodSystem_CAPS_staticFormat(String, Object)

将指定字符串中的一个或多个格式项替换为指定对象的字符串表示形式。

System_CAPS_pubmethodSystem_CAPS_staticFormat(String, Object, Object)

将指定字符串中的格式项替换为两个指定对象的字符串表示形式。

System_CAPS_pubmethodSystem_CAPS_staticFormat(String, Object, Object, Object)

将指定字符串中的格式项替换为三个指定对象的字符串表示形式。

System_CAPS_pubmethodSystem_CAPS_staticFormat(String, Object[])

将指定字符串中的格式项替换为指定数组中相应对象的字符串表示形式。

使用 String.Format 如果您需要将对象、 变量或表达式的值插入到另一个字符串。 例如,您可以插入的值 Decimal 值转换为要显示给用户作为单个字符串的字符串 ︰

Decimal pricePerOunce = 17.36m;
String s = String.Format("The current price is {0} per ounce.",
                         pricePerOunce);
// Result: The current price is 17.36 per ounce.

并且可以控制该值的格式设置 ︰

Decimal pricePerOunce = 17.36m;
String s = String.Format("The current price is {0:C2} per ounce.",
                         pricePerOunce);
// Result if current culture is en-US:
//      The current price is $17.36 per ounce.

除了格式,还可以控制对齐方式和间距。

将字符串插入

String.Format 格式字符串后, 跟一个或多个对象或将其转换为字符串并在格式字符串中指定位置处插入的表达式开头。 例如:

decimal temp = 20.4m;
string s = String.Format("The temperature is {0}°C.", temp);
Console.WriteLine(s);
// Displays 'The temperature is 20.4°C.'

{0} 格式字符串是一个格式项。 0 是将该位置插入其字符串值的索引。 (索引从 0 开始。) 如果要插入的对象不是一个字符串,其 ToString 调用方法以将其转换为一个之前的元素将其插入在结果字符串中。

下面是在对象列表中使用两个格式项和两个对象的另一个示例 ︰

string s = String.Format("At {0}, the temperature is {1}°C.",
                         DateTime.Now, 20.4);
// Output similar to: 'At 4/10/2015 9:29:41 AM, the temperature is 20.4°C.'

可以有任意多个格式项,并且在对象列表中的任意多个对象想,只要每个格式项的索引对象列表中具有匹配的对象。 您也不必担心有关的重载,则调用;编译器将选择适合您。

控制格式设置

您可以按照使用格式字符串来控制如何格式化对象的格式项中的索引。 例如, {0:d} 适用于在对象列表中的第一个对象的"d"格式字符串。 下面是与单个对象的一个示例和两个设置项的格式 ︰

string s = String.Format("It is now {0:d} at {0:t}", DateTime.Now);
// Output similar to: 'It is now 4/10/2015 at 10:04 AM'

类型支持的数字格式字符串,包括所有数值类型 (同时 标准自定义 格式字符串),所有日期和时间 (同时 标准自定义 格式字符串) 和时间间隔 (同时 标准自定义 格式字符串),所有枚举类型 枚举类型, ,和 GUIDs 您还可以向您自己的类型添加支持的格式字符串。

控制间距

您可以定义通过使用如语法插入到结果字符串的字符串的宽度 {0,12}, ,用于插入 12 个字符的字符串。 在这种情况下,第一个对象的字符串表示为右对齐的 12 个字符字段中。 (如果长度超过 12 个字符的字符串表示形式的第一个对象,不过,首选的字段宽度将被忽略,并且整个字符串插入到结果字符串。)

下面的示例定义一个 6 字符字段以保存该字符串"Year"和某些年字符串,以及 15 个字符字段来存放"填充"的字符串和某些填充数据。 请注意,这些字符右对齐字段中。

int[] years = { 2013, 2014, 2015 };
int[] population = { 1025632, 1105967, 1148203 };
String s = String.Format("{0,6} {1,15}\n\n", "Year", "Population");
for(int index = 0; index < years.Length; index++)
   s += String.Format("{0,6} {1,15:N0}\n",
                      years[index], population[index]);
// Result:
//      Year      Population
//
//      2013       1,025,632
//      2014       1,105,967
//      2015       1,148,203
控制对齐方式

默认情况下,字符串是在其字段内右对齐如果指定的字段宽度。 若要从左对齐字符串字段中的,您的前面加字段宽度,负号,如 {0,-12} 来定义 12 个字符右对齐字段。

下面的示例类似于前面的例子中,只是它左对齐标签和数据。

int[] years = { 2013, 2014, 2015 };
int[] population = { 1025632, 1105967, 1148203 };
String s = String.Format("{0,-10} {1,-10}\n\n", "Year", "Population");
for(int index = 0; index < years.Length; index++)
   s += String.Format("{0,-10} {1,-10:N0}\n",
                      years[index], population[index]);
// Result:
//    Year       Population
//
//    2013       1,025,632
//    2014       1,105,967
//    2015       1,148,203

String.Format 使用复合格式设置功能。 有关详细信息,请参阅复合格式设置

选择重载方法的其他指引,请参阅 请勿调用哪些方法?

String String.Format(String format, Object arg0)

格式项替换的字符串表示形式指定的对象 (示例)。

String String.Format(String format, Object arg0, Object arg1)

格式项替换为两个指定对象的字符串表示 (示例)。

String String.Format(String format, Object arg0, Object arg1, Object arg2)

格式项替换为三个指定对象的字符串表示 (示例)。

String String.Format(String format, params Object[] args)

格式项替换的字符串表示形式指定数组中相应对象 (示例)。

String String.Format(IFormatProvider provider, String format, params Object[] args)

格式项替换为指定数组中相应对象的字符串表示,并使用指定的区域性特定格式设置信息 (示例) 或自定义格式设置信息 (示例)。

这是用于参数的完整列表 Format 方法; 请参阅上面使用的每个重载的参数的重载语法。format 参数将使用所有重载。

参数

类型

描述

format

String

一个包含一个或多个格式项的复合格式字符串 (请参阅 格式项)。

arg0

String

第一个或仅要设置格式对象中。

arg1

String

要设置格式的第二个对象。

arg2

String

要设置格式的第三个对象。

args

String[]

零个或多个对象设置格式,请提供以逗号分隔的列表中或作为一个数组。

provider

IFormatProvider

一个对象,提供自定义或区域性特定格式设置信息。

类型 ︰ String
一份 format 其中格式项已替换为相应的参数的字符串表示。

例外

条件

由引发

ArgumentNullException

formatnull

所有重载。

FormatException

format 无效。

- 或 -

格式项的索引小于零,或者大于或等于在参数列表中的参数的数目。

所有重载。

目标

调用

通过使用当前区域性的约定格式化的一个或多个对象。

除了包括重载 provider 参数,则剩余Format 重载包括 String 参数后跟一个或多个对象参数。 因此,您无需确定哪些 Format 想要调用的重载。 您的语言编译器将选择从没有重载的适当重载 provider 基于参数列表的参数。 例如,如果参数列表中包含五个参数,编译器将调用 Format(String, Object[]) 方法。

通过使用特定区域性的约定格式化的一个或多个对象。

每个Format开头的重载 provider 参数后跟 String 参数和一个或多个对象参数。 因此,您不需要确定哪个特定 Format 想要调用的重载。 您的语言编译器将选择从已重载的适当重载 provider 基于参数列表的参数。 例如,如果参数列表中包含五个参数,编译器将调用 Format(IFormatProvider, String, Object[]) 方法。

通过执行自定义格式设置操作 ICustomFormatter 实现或 IFormattable 实现。

任何具有四个重载 provider 参数。 编译器将选择从已重载的适当重载 provider 基于参数列表的参数。

每个重载 Format 方法使用 复合格式设置功能 包括从零开始索引的占位符称为格式项,复合格式字符串中。 在运行时,每个格式项替换的字符串表示形式的参数列表中的对应参数。 如果参数的值是 null, ,格式项都替换为与 String.Empty 例如,以下调用到 Format(String, Object, Object, Object) 方法包括三个格式项、 与 {0},{1 \},\ {2,将格式字符串和参数列表包含三个项。

DateTime dat = new DateTime(2012, 1, 17, 9, 30, 0); 
string city = "Chicago";
int temp = -16;
string output = String.Format("At {0} in {1}, the temperature was {2} degrees.",
                              dat, city, temp);
Console.WriteLine(output);
// The example displays the following output:
//    At 1/17/2012 9:30:00 AM in Chicago, the temperature was -16 degrees.   

格式项具有以下语法 ︰


{
index[,alignment][ :formatString] }

括号表示可选元素。 括号和右大括号是必需的。 (包括文本左或右大括号中的格式字符串,请参阅中的"转义大括号"一节 复合格式设置 文章。)

例如,格式项为格式的货币值,可能会显示如下 ︰

String.Format("{0,-10:C}", 126347.89m);         

格式项具有以下元素 ︰

索引

字符串表示形式将是的参数的从零开始的索引包含在字符串中的此位置。 如果此参数为 null, ,将在此位置在字符串中包含一个空字符串。

对齐方式

可选。 一个有符号的整数,它指示将它插入参数以及它是右对齐 (正整数) 还是左对齐 (负整数) 到该字段的总长度。 如果省略 对齐, ,不能有前导或尾随空格的字段中插入的字符串表示形式的对应参数。

如果的值 对齐 参数要插入的长度少于 对齐 将被忽略并使用参数的字符串表示形式的长度作为字段宽度。

格式说明符

可选。 一个字符串,指定相应的参数结果字符串的格式。 如果省略 formatString, ,相应的参数的无参数 ToString 方法调用以生成其字符串表示形式。 如果指定 formatString, ,引用的格式项的参数必须实现 IFormattable 接口。 支持格式字符串的类型包括 ︰

但是,请注意,任何自定义类型可以实现 IFormattable 或扩展现有类型的 IFormattable 实现。

下面的示例使用 alignmentformatString 参数才能生成格式化的输出。

using System;

public class Example
{
   public static void Main()
   {
      // Create array of 5-tuples with population data for three U.S. cities, 1940-1950.
      Tuple<string, DateTime, int, DateTime, int>[] cities = 
          { Tuple.Create("Los Angeles", new DateTime(1940, 1, 1), 1504277, 
                         new DateTime(1950, 1, 1), 1970358),
            Tuple.Create("New York", new DateTime(1940, 1, 1), 7454995, 
                         new DateTime(1950, 1, 1), 7891957),  
            Tuple.Create("Chicago", new DateTime(1940, 1, 1), 3396808, 
                         new DateTime(1950, 1, 1), 3620962),  
            Tuple.Create("Detroit", new DateTime(1940, 1, 1), 1623452, 
                         new DateTime(1950, 1, 1), 1849568) };

      // Display header
      string header = String.Format("{0,-12}{1,8}{2,12}{1,8}{2,12}{3,14}\n",
                                    "City", "Year", "Population", "Change (%)");
      Console.WriteLine(header);
      string output;      
      foreach (var city in cities) {
         output = String.Format("{0,-12}{1,8:yyyy}{2,12:N0}{3,8:yyyy}{4,12:N0}{5,14:P1}",
                                city.Item1, city.Item2, city.Item3, city.Item4, city.Item5,
                                (city.Item5 - city.Item3)/ (double)city.Item3);
         Console.WriteLine(output);
      }
   }
}
// The example displays the following output:
//    City            Year  Population    Year  Population    Change (%)
//    
//    Los Angeles     1940   1,504,277    1950   1,970,358        31.0 %
//    New York        1940   7,454,995    1950   7,891,957         5.9 %
//    Chicago         1940   3,396,808    1950   3,620,962         6.6 %
//    Detroit         1940   1,623,452    1950   1,849,568        13.9 %

格式项都按顺序处理从字符串的开头。 每个格式项的索引对应于该方法的参数列表中的对象。 Format 方法检索该参数,并派生其字符串表示形式,如下所示 ︰

有关的示例,截获对调用 ICustomFormatter.Format 方法,并允许您以查看哪些信息 Format 方法传递到格式设置方法,以每个格式项在复合格式字符串中,请参阅 示例 7 ︰ 一个截距提供程序和罗马数字格式化程序

Format 方法抛出异常 FormatException 索引项的索引是否大于或等于参数列表中的参数数目的异常。 但是, format 可以包括多个格式项不是有参数,前提是多个格式项具有相同的索引。 在调用 Format(String, Object) 在以下示例中,参数列表的方法具有一个参数,但该格式字符串包含两个格式项 ︰ 一个显示一个数字,十进制值,另一个显示其十六进制值。

public class Example
{
   public static void Main()
   {
      short[] values= { Int16.MinValue, -27, 0, 1042, Int16.MaxValue };
      Console.WriteLine("{0,10}  {1,10}\n", "Decimal", "Hex");
      foreach (short value in values)
      {
         string formatString = String.Format("{0,10:G}: {0,10:X}", value);
         Console.WriteLine(formatString);
      }   
   }
}
// The example displays the following output:
//       Decimal         Hex
//    
//        -32768:       8000
//           -27:       FFE5
//             0:          0
//          1042:        412
//         32767:       7FFF

通常情况下,参数列表中的对象将转换为其字符串表示形式通过使用当前区域性的约定返回此 CultureInfo.CurrentCulture 属性。 您可以通过调用的重载之一来控制此行为 Format 包括 provider 参数。 provider 参数是 IFormatProvider 实现,提供用于控制格式设置的自定义和区域性特定格式设置信息处理。

IFormatProvider 接口具有一个成员, GetFormat, ,它是负责返回提供的格式设置信息的对象。 .NET Framework 具有三个 IFormatProvider 提供区域性特定格式设置的实现 ︰

您还可以调用的重载任何 Format 方法具有 provider 参数 Format(IFormatProvider, String, Object[]) 重载来执行自定义格式设置操作。 例如,您无法设置整数格式作为一个标识号或电话号码。 若要执行自定义格式设置,您 provider 参数必须同时实现 IFormatProviderICustomFormatter 接口。Format 方法传递 ICustomFormatter 实现作为 provider 参数, Format 方法调用其 IFormatProvider.GetFormat 实现,并请求类型的对象 ICustomFormatter 然后,它调用返回 ICustomFormatter 对象的 Format 方法来设置格式的复合字符串中每个格式项传递给它。

有关提供自定义格式设置解决方案的详细信息,请参阅 如何:定义和使用自定义数值格式提供程序ICustomFormatter 将整数转换为带格式自定义数字示例,请参阅 示例 6 ︰ 自定义格式设置操作 将无符号的字节转换为罗马数字示例,请参阅 示例 7 ︰ 一个截距提供程序和罗马数字格式化程序

下面的示例使用 Format(String, Object) 方法嵌入字符串中间的一个人的年龄。

using System;

[assembly: CLSCompliant(true)]
public class Example
{
   public static void Main()
   {
      DateTime birthdate = new DateTime(1993, 7, 28);
      DateTime[] dates = { new DateTime(1993, 8, 16), 
                           new DateTime(1994, 7, 28), 
                           new DateTime(2000, 10, 16), 
                           new DateTime(2003, 7, 27), 
                           new DateTime(2007, 5, 27) };

      foreach (DateTime dateValue in dates)
      {
         TimeSpan interval = dateValue - birthdate;
         // Get the approximate number of years, without accounting for leap years.
         int years = ((int) interval.TotalDays) / 365;
         // See if adding the number of years exceeds dateValue.
         string output;
         if (birthdate.AddYears(years) <= dateValue) {
            output = String.Format("You are now {0} years old.", years);
            Console.WriteLine(output);
         }   
         else {
            output = String.Format("You are now {0} years old.", years - 1);
            Console.WriteLine(output);
         }      
      }
   }
}
// The example displays the following output:
//       You are now 0 years old.
//       You are now 1 years old.
//       You are now 7 years old.
//       You are now 9 years old.
//       You are now 13 years old.

此示例使用 Format(String, Object, Object) 方法以显示时间和温度数据存储在一个泛型 Dictionary<TKey, TValue> 对象。 请注意,格式字符串三个格式项,尽管只有两个要格式化的对象。 这是因为列表 (日期和时间值) 中的第一个对象使用两个格式项 ︰ 第一个格式项目将显示时间和第二个显示的日期。

using System;
using System.Collections.Generic;

public class Example
{
   public static void Main()
   {
      Dictionary<DateTime, Double> temperatureInfo = new Dictionary<DateTime, Double>(); 
      temperatureInfo.Add(new DateTime(2010, 6, 1, 14, 0, 0), 87.46);
      temperatureInfo.Add(new DateTime(2010, 12, 1, 10, 0, 0), 36.81);

      Console.WriteLine("Temperature Information:\n");
      string output;   
      foreach (var item in temperatureInfo)
      {
         output = String.Format("Temperature at {0,8:t} on {0,9:d}: {1,5:N1}°F", 
                                item.Key, item.Value);
         Console.WriteLine(output);
      }
   }
}
// The example displays the following output:
//       Temperature Information:
//       
//       Temperature at  2:00 PM on  6/1/2010:  87.5°F
//       Temperature at 10:00 AM on 12/1/2010:  36.8°F

此示例使用 Format(String, Object, Object, Object) 方法来创建字符串,其中说明了一个布尔值结果 And 具有两个整数值操作。 请注意,格式字符串包括六个格式项,但该方法具有在其参数列表中,只有三个项,因为每一项格式化以两个不同的方式。

using System;

public class Example
{
   public static void Main()
   {
      string formatString = "    {0,10} ({0,8:X8})\n" + 
                            "And {1,10} ({1,8:X8})\n" + 
                            "  = {2,10} ({2,8:X8})";
      int value1 = 16932;
      int value2 = 15421;
      string result = String.Format(formatString, 
                                    value1, value2, value1 & value2);
      Console.WriteLine(result);
   }
}
// The example displays the following output:
//                16932 (00004224)
//       And      15421 (00003C3D)
//         =         36 (00000024)

此示例创建一个字符串,包含在特定日期的最高价和最温度上的数据。 复合格式字符串具有五个格式项在 C# 示例和六个 in Visual Basic 示例。 两个格式项定义其相应的值的字符串表示形式的宽度和第一个格式项还包括一个标准日期和时间格式字符串。

using System;

public class Example
{
   public static void Main()
   {
      DateTime date1 = new DateTime(2009, 7, 1);
      TimeSpan hiTime = new TimeSpan(14, 17, 32);
      decimal hiTemp = 62.1m; 
      TimeSpan loTime = new TimeSpan(3, 16, 10);
      decimal loTemp = 54.8m; 

      string result1 = String.Format("Temperature on {0:d}:\n{1,11}: {2} degrees (hi)\n{3,11}: {4} degrees (lo)", 
                                     date1, hiTime, hiTemp, loTime, loTemp);
      Console.WriteLine(result1);
      Console.WriteLine();

      string result2 = String.Format("Temperature on {0:d}:\n{1,11}: {2} degrees (hi)\n{3,11}: {4} degrees (lo)", 
                                     new object[] { date1, hiTime, hiTemp, loTime, loTemp });
      Console.WriteLine(result2);
   }
}
// The example displays the following output:
//       Temperature on 7/1/2009:
//          14:17:32: 62.1 degrees (hi)
//          03:16:10: 54.8 degrees (lo)
//       Temperature on 7/1/2009:
//          14:17:32: 62.1 degrees (hi)
//          03:16:10: 54.8 degrees (lo)

您还可以传递格式化为一个数组的对象而不是参数列表。

using System;

public class CityInfo
{
   public CityInfo(String name, int population, Decimal area, int year)
   {
      this.Name = name;
      this.Population = population;
      this.Area = area;
      this.Year = year;
   }

   public readonly String Name; 
   public readonly int Population;
   public readonly Decimal Area;
   public readonly int Year;
}

public class Example
{
   public static void Main()
   {
      CityInfo nyc2010 = new CityInfo("New York", 8175133, 302.64m, 2010);
      ShowPopulationData(nyc2010);
      CityInfo sea2010 = new CityInfo("Seattle", 608660, 83.94m, 2010);      
      ShowPopulationData(sea2010); 
   }

   private static void ShowPopulationData(CityInfo city)
   {
      object[] args = { city.Name, city.Year, city.Population, city.Area };
      String result = String.Format("{0} in {1}: Population {2:N0}, Area {3:N1} sq. feet", 
                                    args);
      Console.WriteLine(result); 
   }
}
// The example displays the following output:
//       New York in 2010: Population 8,175,133, Area 302.6 sq. feet
//       Seattle in 2010: Population 608,660, Area 83.9 sq. feet

此示例使用 Format(IFormatProvider, String, Object[]) 方法以显示通过使用一些不同的区域性的字符串表示形式某些日期和时间值和数值。

using System;
using System.Globalization;

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

      DateTime dateToDisplay = new DateTime(2009, 9, 1, 18, 32, 0);
      double value = 9164.32;

      Console.WriteLine("Culture     Date                                Value\n");
      foreach (string cultureName in cultureNames)
      {
         CultureInfo culture = new CultureInfo(cultureName);
         string output = String.Format(culture, "{0,-11} {1,-35:D} {2:N}", 
                                       culture.Name, dateToDisplay, value);
         Console.WriteLine(output);
      }    
   }
}
// The example displays the following output:
//    Culture     Date                                Value
//    
//    en-US       Tuesday, September 01, 2009         9,164.32
//    fr-FR       mardi 1 septembre 2009              9 164,32
//    de-DE       Dienstag, 1. September 2009         9.164,32
//    es-ES       martes, 01 de septiembre de 2009    9.164,32

此示例定义一个整数值的格式设置为在窗体 x xxxxx xx 客户帐号的格式提供。

using System;

public class TestFormatter
{
   public static void Main()
   {
      int acctNumber = 79203159;
      Console.WriteLine(String.Format(new CustomerFormatter(), "{0}", acctNumber));
      Console.WriteLine(String.Format(new CustomerFormatter(), "{0:G}", acctNumber));
      Console.WriteLine(String.Format(new CustomerFormatter(), "{0:S}", acctNumber));
      Console.WriteLine(String.Format(new CustomerFormatter(), "{0:P}", acctNumber));
      try {
         Console.WriteLine(String.Format(new CustomerFormatter(), "{0:X}", acctNumber));
      }
      catch (FormatException e) {
         Console.WriteLine(e.Message);
      }
   }
}

public class CustomerFormatter : 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 (! this.Equals(formatProvider))
      {
         return null;
      }
      else
      {
         if (String.IsNullOrEmpty(format)) 
            format = "G";

         string customerString = arg.ToString();
         if (customerString.Length < 8)
            customerString = customerString.PadLeft(8, '0');

         format = format.ToUpper();
         switch (format)
         {
            case "G":
               return customerString.Substring(0, 1) + "-" +
                                     customerString.Substring(1, 5) + "-" +
                                     customerString.Substring(6);
            case "S":                          
               return customerString.Substring(0, 1) + "/" +
                                     customerString.Substring(1, 5) + "/" +
                                     customerString.Substring(6);
            case "P":                          
               return customerString.Substring(0, 1) + "." +
                                     customerString.Substring(1, 5) + "." +
                                     customerString.Substring(6);
            default:
               throw new FormatException( 
                         String.Format("The '{0}' format specifier is not supported.", format));
         }
      }   
   }
}
// The example displays the following output:
//       7-92031-59
//       7-92031-59
//       7/92031/59
//       7.92031.59
//       The 'X' format specifier is not supported.

此示例定义一个自定义格式提供程序实现 ICustomFormatterIFormatProvider 接口做两件事 ︰

  • 它显示的参数传递给其 ICustomFormatter.Format 实现。 这使我们能够查看哪些参数 Format(IFormatProvider, String, Object[]) 方法将传递给它会尝试设置格式的每个对象的自定义格式设置实现。 在调试您的应用程序时,这很有用。

  • 要设置格式的对象是否是可使用"R"标准格式字符串设置格式的无符号的字节值,自定义格式化程序格式的数字值设置为罗马数字。

using System;
using System.Globalization;

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

   public string Format(String format, Object obj, IFormatProvider provider) 
   {
      // Display information about method call.
      string formatString = format ?? "<null>";
      Console.WriteLine("Provider: {0}, Object: {1}, Format String: {2}",
                        provider, obj ?? "<null>", formatString);

      if (obj == null) return String.Empty;

      // If this is a byte and the "R" format string, format it with Roman numerals.
      if (obj is Byte && formatString.ToUpper().Equals("R")) {
         Byte value = (Byte) obj;
         int remainder;
         int result;
         String returnString = String.Empty;

         // Get the hundreds digit(s)
         result = Math.DivRem(value, 100, out remainder);
         if (result > 0)  
            returnString = new String('C', result);
         value = (Byte) remainder;
         // Get the 50s digit
         result = Math.DivRem(value, 50, out remainder);
         if (result == 1)
            returnString += "L";
         value = (Byte) remainder;
         // Get the tens digit.
         result = Math.DivRem(value, 10, out remainder);
         if (result > 0)
            returnString += new String('X', result);
         value = (Byte) remainder; 
         // Get the fives digit.
         result = Math.DivRem(value, 5, out remainder);
         if (result > 0)
            returnString += "V";
         value = (Byte) remainder;
         // Add the ones digit.
         if (remainder > 0) 
            returnString += new String('I', remainder);

         // Check whether we have too many X characters.
         int pos = returnString.IndexOf("XXXX");
         if (pos >= 0) {
            int xPos = returnString.IndexOf("L"); 
            if (xPos >= 0 & xPos == pos - 1)
               returnString = returnString.Replace("LXXXX", "XC");
            else
               returnString = returnString.Replace("XXXX", "XL");   
         }
         // Check whether we have too many I characters
         pos = returnString.IndexOf("IIII");
         if (pos >= 0)
            if (returnString.IndexOf("V") >= 0)
               returnString = returnString.Replace("VIIII", "IX");
            else
               returnString = returnString.Replace("IIII", "IV");    

         return returnString; 
      }   

      // Use default for all other formatting.
      if (obj is IFormattable)
         return ((IFormattable) obj).ToString(format, CultureInfo.CurrentCulture);
      else
         return obj.ToString();
   }
}

public class Example
{
   public static void Main()
   {
      int n = 10;
      double value = 16.935;
      DateTime day = DateTime.Now;
      InterceptProvider provider = new InterceptProvider();
      Console.WriteLine(String.Format(provider, "{0:N0}: {1:C2} on {2:d}\n", n, value, day));
      Console.WriteLine(String.Format(provider, "{0}: {1:F}\n", "Today: ", 
                                      (DayOfWeek) DateTime.Now.DayOfWeek));
      Console.WriteLine(String.Format(provider, "{0:X}, {1}, {2}\n", 
                                      (Byte) 2, (Byte) 12, (Byte) 199));
      Console.WriteLine(String.Format(provider, "{0:R}, {1:R}, {2:R}\n", 
                                      (Byte) 2, (Byte) 12, (Byte) 199));
   }
}
// The example displays the following output:
//    Provider: InterceptProvider, Object: 10, Format String: N0
//    Provider: InterceptProvider, Object: 16.935, Format String: C2
//    Provider: InterceptProvider, Object: 1/31/2013 6:10:28 PM, Format String: d
//    10: $16.94 on 1/31/2013
//    
//    Provider: InterceptProvider, Object: Today: , Format String: <null>
//    Provider: InterceptProvider, Object: Thursday, Format String: F
//    Today: : Thursday
//    
//    Provider: InterceptProvider, Object: 2, Format String: X
//    Provider: InterceptProvider, Object: 12, Format String: <null>
//    Provider: InterceptProvider, Object: 199, Format String: <null>
//    2, 12, 199
//    
//    Provider: InterceptProvider, Object: 2, Format String: R
//    Provider: InterceptProvider, Object: 12, Format String: R
//    Provider: InterceptProvider, Object: 199, Format String: R
//    II, XII, CXCIX

.NET Framework

中支持所有重载 ︰ 4.5、 4、 3.5、 3.0、 2.0、 1.1、 1.0

.NET Framework Client Profile

所有重载都受都支持中 ︰ 4、 3.5 SP1

可移植类库

Format(String, Object[])Format(IFormatProvider, String, Object[]) 支持

适用于 Windows 应用商店应用的 .NET

Format(String, Object[])Format(IFormatProvider, String, Object[]) 在 Windows 8 中支持

格式项的常规语法是 ︰

{index[,alignment][: formatString]}

其中 对齐 字段宽度定义一个带符号整数。 如果此值为负,则它是字段中的文本左对齐。 如果为正数,文本为右对齐。

所有 标准数字格式字符串 except (它们使用仅包含整数) 的"D"、"G"、"R"和"X"允许在结果字符串中定义的小数位数的精度说明符。 下面的示例使用标准数字格式字符串来控制结果字符串中的十进制数字的数目。

using System;

public class Example
{
   public static void Main()
   {
      object[] values = { 1603, 1794.68235, 15436.14 };
      string result;
      foreach (var value in values) {
         result = String.Format("{0,12:C2}   {0,12:E3}   {0,12:F4}   {0,12:N3}  {1,12:P2}\n",
                                Convert.ToDouble(value), Convert.ToDouble(value) / 10000);
         Console.WriteLine(result);
      }                           
   }
}
// The example displays the following output:
//       $1,603.00     1.603E+003      1603.0000      1,603.000       16.03 %
//    
//       $1,794.68     1.795E+003      1794.6824      1,794.682       17.95 %
//    
//      $15,436.14     1.544E+004     15436.1400     15,436.140      154.36 %

如果您使用 自定义数字格式字符串, ,使用"0"格式说明符来控制结果字符串中的十进制数字,如以下示例所示的数目。

using System;

public class Example
{
   public static void Main()
   {
      decimal value = 16309.5436m;
      string result = String.Format("{0,12:#.00000} {0,12:0,000.00} {0,12:000.00#}", 
                                    value);
      Console.WriteLine(result);
   }
}
// The example displays the following output:
//        16309.54360    16,309.54    16309.544

默认情况下,格式设置操作将仅显示非零的整数位数。 如果要设置格式的整数,您可以使用精度说明符与"D"和"X"标准格式字符串来控制的数字个数。

using System;

public class Example
{
   public static void Main()
   {
      int value = 1326;
      string result = String.Format("{0,10:D6} {0,10:X8}", value);
      Console.WriteLine(result);
   }
}
// The example displays the following output:
//     001326   0000052E

要通过使用"0"来生成具有指定数目的整数位的结果字符串的整数或带前导零的浮点数,可以填充 自定义数字格式说明符, ,如下面的示例所示。

using System;

public class Example
{
   public static void Main()
   {
      int value = 16342;
      string result = String.Format("{0,18:00000000} {0,18:00000000.000} {0,18:000,0000,000.0}", 
                                    value);
      Console.WriteLine(result);
   }
}
// The example displays the following output:
//           00016342       00016342.000    0,000,016,342.0

没有任何实际的限制。 第二个参数 Format(IFormatProvider, String, Object[]) 方法标有 ParamArrayAttribute 特性,这使您能承受的分隔的列表或对象数组作为格式列表。

例如,如何防止不能引发下面的方法调用 FormatException 异常?

result = String.Format("The text has {0} '{' characters and {1} '}' characters.",
                       nOpen, nClose);

单个括号或右大括号始终被解释为开头或结尾的格式项中。 若要按原义解释,它必须进行转义。 通过添加另一个大括号转义大括号 ("{{"和"}}"而不是"{"和"}"),如下面的方法调用 ︰

result = String.Format("The text has {0} '{{' characters and {1} '}}' characters.",
                       nOpen, nClose);

但是,即使转义大括号是轻松地误解。 我们建议你在格式列表中包含大括号和格式项用于将它们插入在结果字符串中,如以下示例所示。

result = String.Format("The text has {0} '{1}' characters and {2} '{3}' characters.",
                       nOpen, "{", nClose, "}");

该异常的最常见原因是,不会与格式列表中的对象相对应的格式项的索引。 通常,这表示已经 misnumbered 格式项的索引或忘记了要包含在格式列表中的对象。 有时,例外情况是打字错误; 结果例如,典型的错误是输错"["(左的括号) 而不是"{"(左大括号)。

例如,下面的代码引发 FormatException 异常 ︰

using System;
using System.Collections.Generic;

public class Example
{
   public static void Main()
   {
      Random rnd = new Random();
      int[]  numbers = new int[4];
      int total = 0;
      for (int ctr = 0; ctr <= 2; ctr++) {
         int number = rnd.Next(1001);
         numbers[ctr] = number;
         total += number;
      }   
      numbers[3] = total;
      Console.WriteLine("{0} + {1} + {2} = {3}", numbers);   
   }
}

这是编译器重载决策的问题。 因为编译器不能将整数的数组转换为一个对象数组,它将整数数组视为单个参数,因此它将调用 Format(String, Object) 方法。 因为有四个格式项,但仅格式列表中的单个项目,将引发异常。

因为既不 Visual Basic 和 C# 可以将一个整数数组转换为一个对象数组,你必须自己来执行转换,然后再调 Format(String, Object[]) 方法。 下面的示例提供了一种实现。

using System;
using System.Collections.Generic;

public class Example
{
   public static void Main()
   {
      Random rnd = new Random();
      int[]  numbers = new int[4];
      int total = 0;
      for (int ctr = 0; ctr <= 2; ctr++) {
         int number = rnd.Next(1001);
         numbers[ctr] = number;
         total += number;
      }   
      numbers[3] = total;
      object[] values = new object[numbers.Length];
      numbers.CopyTo(values, 0);
      Console.WriteLine("{0} + {1} + {2} = {3}", values);   
   }
}
返回页首
显示:
© 2016 Microsoft