String.Format 方法

 
 

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

命名空间:   System

 名称说明
System_CAPS_pubmethodSystem_CAPS_static Format(IFormatProvider, String, Object)

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

System_CAPS_pubmethodSystem_CAPS_static Format(IFormatProvider, String, Object, Object)

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

System_CAPS_pubmethodSystem_CAPS_static Format(IFormatProvider, String, Object, Object, Object)

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

System_CAPS_pubmethodSystem_CAPS_static Format(IFormatProvider, String, Object[])

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

System_CAPS_pubmethodSystem_CAPS_static Format(String, Object)

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

System_CAPS_pubmethodSystem_CAPS_static Format(String, Object, Object)

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

System_CAPS_pubmethodSystem_CAPS_static Format(String, Object, Object, Object)

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

System_CAPS_pubmethodSystem_CAPS_static Format(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

format 为 null

所有重载。

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);

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

 
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);   
   }
}
posted @ 2017-09-20 21:26  执念、旧时光  阅读(3723)  评论(0编辑  收藏  举报