String.Format 方法

定义

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

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

有关 String.Format 方法的常规文档,请参阅备注部分。

重载

Format(String, Object)

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

Format(String, Object[])

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

Format(IFormatProvider, String, Object)

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

Format(IFormatProvider, String, Object[])

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

Format(String, Object, Object)

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

Format(IFormatProvider, String, Object, Object)

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

Format(String, Object, Object, Object)

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

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

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

示例

许多调用 方法的示例都通过本文的"备注" Format 部分进行交错。

还可以下载一组完整的示例,其中包括适用于 String.Format C# 的 .NET Core 项目

下面是本文中包含的一些示例:

创建格式字符串

插入字符串
格式项
设置索引相同的项的格式

控制格式化输出

控制格式设置
控制间距
控制对齐方式
控制整数位数
控制小数点分隔符后的位数
在结果字符串中包括文本大括号

使格式字符串区分区域性

区分区域性的格式设置

自定义格式设置操作

自定义格式设置操作
截距提供程序和拉丁数字格式化程序

注解

重要

可以不调用 String.Format 方法或使用复合格式字符串,而改为使用内插字符串(如果受语言支持的话)。 内插字符串是包含内插表达式的字符串。 每个内插表达式都使用表达式的值进行解析,并在分配字符串时包含在结果字符串中。 有关详细信息,请参阅字符串内插(C# 参考)内插字符串(Visual Basic 参考)

本节内容:

开始处理字符串. 格式方法
我要调用哪种方法?
Format 方法 brief
格式项
如何设置参数的格式
设置具有相同索引的项的格式
格式设置和区域性
自定义格式设置操作
字符串格式 Q &

开始处理字符串. 格式方法

String.Format如果需要将对象、变量或表达式的值插入到另一个字符串,请使用。 例如,可以将值的值插入 Decimal 字符串中,以单个字符串的形式向用户显示该值:

Decimal pricePerOunce = (Decimal)17.36;
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} per ounce.",
                         pricePerOunce);
Console.WriteLine(s);
// Result: The current price is 17.36 per ounce.
Dim pricePerOunce As Decimal = 17.36d
Dim s As String = String.Format("The current price is {0} per ounce.",
                                pricePerOunce)
' Result: The current price is 17.36 per ounce.

您可以控制该值的格式:

Decimal pricePerOunce = (Decimal)17.36;
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.
Decimal pricePerOunce = 17.36m;
String s = String.Format("The current price is {0:C2} per ounce.",
                         pricePerOunce);
Console.WriteLine(s);
// Result if current culture is en-US:
//      The current price is $17.36 per ounce.
Dim pricePerOunce As Decimal = 17.36d
Dim s As String = 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 = (Decimal)20.4;
String^ s = String::Format("The temperature is {0}°C.", temp);
Console::WriteLine(s);
// Displays 'The temperature is 20.4°C.'
decimal temp = 20.4m;
string s = String.Format("The temperature is {0}°C.", temp);
Console.WriteLine(s);
// Displays 'The temperature is 20.4°C.'
Dim temp As Decimal = 20.4d
Dim s As String = 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.'
string s = String.Format("At {0}, the temperature is {1}°C.",
                         DateTime.Now, 20.4);
Console.WriteLine(s);
// Output similar to: 'At 4/10/2015 9:29:41 AM, the temperature is 20.4°C.'
Dim s As String = String.Format("At {0}, the temperature is {1}°C.",
                                Date.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'
string s = String.Format("It is now {0:d} at {0:t}", DateTime.Now);
Console.WriteLine(s);
// Output similar to: 'It is now 4/10/2015 at 10:04 AM'
Dim s As String = String.Format("It is now {0:d} at {0:t}",
                                Date.Now)
' Output similar to: 'It is now 4/10/2015 at 10:04 AM'

许多类型都支持格式字符串,其中包括标准和定义格式字符串 (的所有数字类型) 、标准和定义格式字符串) (的所有日期和时间均为标准和定义格式字符串 (、所有枚举类型枚举类型以及guid。 您还可以将对格式字符串的支持添加到您自己的类型中。

控件间距

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

下面的示例定义了一个包含字符串 "Year" 和一些年份字符串的6字符字段,以及一个包含字符串 "人口" 和一些人口数据的15个字符的字段。 请注意,字符在字段中右对齐。

array<int>^ years = { 2013, 2014, 2015 };
array<int>^ population = { 1025632, 1105967, 1148203 };
StringBuiler^ sb = gcnew StringBuilder();
sb->Append(String::Format("{0,6} {1,15}\n\n", "Year", "Population"));
for(int index = 0; index < years->Length; index++)
   sb->AppendFormat("{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
     int[] years = { 2013, 2014, 2015 };
     int[] population = { 1025632, 1105967, 1148203 };
     var sb = new System.Text.StringBuilder();
     sb.Append(String.Format("{0,6} {1,15}\n\n", "Year", "Population"));
     for (int index = 0; index < years.Length; index++)
        sb.Append(String.Format("{0,6} {1,15:N0}\n", years[index], population[index]));

     Console.WriteLine(sb);

     // Result:
     //      Year      Population
     //
     //      2013       1,025,632
     //      2014       1,105,967
     //      2015       1,148,203
Dim years() As Integer = { 2013, 2014, 2015 }
Dim population() As Integer  = { 1025632, 1105967, 1148203 }
Dim sb As New StringBuilder()
sb.Append(String.Format("{0,6} {1,15}{2}{2}",
                        "Year", "Population", vbCrLf))
For index As Integer = 0 To years.Length - 1
   sb.AppendFormat("{0,6} {1,15:N0}{2}",
                   years(index), population(index), vbCrLf)
Next
' Result:
'      Year      Population
'
'      2013       1,025,632
'      2014       1,105,967
'      2015       1,148,203

控件对齐

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

下面的示例与上一个示例类似,不同之处在于它会将标签和数据保持一致。

array<int>^ years = { 2013, 2014, 2015 };
array<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
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]);
Console.WriteLine($"\n{s}");
// Result:
//    Year       Population
//
//    2013       1,025,632
//    2014       1,105,967
//    2015       1,148,203
Dim years() As Integer = { 2013, 2014, 2015 }
Dim population() As Integer  = { 1025632, 1105967, 1148203 }
Dim s As String = String.Format("{0,-10} {1,-10}{2}{2}",
                                "Year", "Population", vbCrLf)
For index As Integer = 0 To years.Length - 1
   s += String.Format("{0,-10} {1,-10:N0}{2}",
                      years(index), population(index), vbCrLf)
Next
' Result:
'    Year       Population
'
'    2013       1,025,632
'    2014       1,105,967
'    2015       1,148,203

String.Format 使用复合格式设置功能。 有关更多信息,请参见复合格式设置

我要调用哪种方法?

功能 调用
使用当前区域性的约定设置一个或多个对象的格式。 除了包含参数的重载以外 provider ,其余 Format 重载包含一个参数, String 后跟一个或多个对象参数。 因此,不必确定要 Format 调用的重载。 根据参数列表,语言编译器会从没有参数的重载中选择相应的重载 provider 。 例如,如果参数列表具有五个参数,则编译器将调用 Format(String, Object[]) 方法。
通过使用特定区域性的约定来设置一个或多个对象的格式。 Format 参数开头的每个重载 provider 后跟一个 String 参数和一个或多个对象参数。 因此,不必确定要调用的特定 Format 重载。 语言编译器根据参数列表,从具有参数的重载中选择适当的重载 provider 。 例如,如果参数列表具有五个参数,则编译器将调用 Format(IFormatProvider, String, Object[]) 方法。
使用实现或实现执行自定义格式设置操作 ICustomFormatter IFormattable 四个具有参数的重载中的任何一个 provider 。 编译器根据参数列表,从具有参数的重载中选择适当的重载 provider

Format 方法 brief

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

using namespace System;

void main()
{
   DateTime^ dat = gcnew 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.
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 output like the following:
//    At 1/17/2012 9:30:00 AM in Chicago, the temperature was -16 degrees.
Dim dat As Date = #1/17/2012 9:30AM# 
Dim city As String = "Chicago"
Dim temp As Integer = -16
Dim output As String = 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}", (Decimal) 126347.89);
var value = String.Format("{0,-10:C}", 126347.89m);         
Console.WriteLine(value);
String.Format("{0,-10:C}", 126347.89d)

格式项包含以下元素:

index
自变量的从零开始的索引,其字符串表示形式将包含在字符串中的此位置。 如果此参数为 null ,则字符串中此位置将包含空字符串。

关联
可选。 一个有符号整数,它指示要插入自变量的字段的总长度,并指定该参数是右对齐的, (是正整数) 还是) 负整数 (左对齐。 如果省略 对齐方式,则会在不带前导空格或尾随空格的字段中插入相应参数的字符串表示形式。

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

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

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

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

using namespace System;

void main()
{
   // Create array of 5-tuples with population data for three U.S. cities, 1940-1950.
   array<Tuple<String^, DateTime, int, DateTime, int>^>^ cities = gcnew array<Tuple<String^, DateTime, int, DateTime, int>^> 
         { gcnew Tuple<String^, DateTime, int, DateTime, int>("Los Angeles", DateTime(1940, 1, 1), 1504277, 
                        DateTime(1950, 1, 1), 1970358),
         gcnew Tuple<String^, DateTime, int, DateTime, int>("New York", DateTime(1940, 1, 1), 7454995, 
                        DateTime(1950, 1, 1), 7891957),  
         gcnew Tuple<String^, DateTime, int, DateTime, int>("Chicago", DateTime(1940, 1, 1), 3396808, 
                        DateTime(1950, 1, 1), 3620962),  
         gcnew Tuple<String^, DateTime, int, DateTime, int>("Detroit", DateTime(1940, 1, 1), 1623452, 
                        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;      
   for each (Tuple<String^, DateTime, int, DateTime, int>^ 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 %
// 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
var header = String.Format("{0,-12}{1,8}{2,12}{1,8}{2,12}{3,14}\n",
                              "City", "Year", "Population", "Change (%)");
Console.WriteLine(header);
foreach (var city in cities) {
   var 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 %
Module Example
   Public Sub Main()
      ' Create array of 5-tuples with population data for three U.S. cities, 1940-1950.
      Dim cities()  = _
          { Tuple.Create("Los Angeles", #1/1/1940#, 1504277, #1/1/1950#, 1970358),
            Tuple.Create("New York", #1/1/1940#, 7454995, #1/1/1950#, 7891957),  
            Tuple.Create("Chicago", #1/1/1940#, 3396808, #1/1/1950#, 3620962),  
            Tuple.Create("Detroit", #1/1/1940#, 1623452, #1/1/1950#, 1849568) }

      ' Display header
      Dim header As String = String.Format("{0,-12}{1,8}{2,12}{1,8}{2,12}{3,14}",
                                           "City", "Year", "Population", "Change (%)")
      Console.WriteLine(header)
      Console.WriteLine()
      For Each city In cities
         Dim 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)/city.Item3)
         Console.WriteLine(output)
      Next
   End Sub
End Module
' 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 方法为复合格式字符串中的每个格式项传递到格式设置方法的信息,请参阅 示例:截获提供程序和罗马数字格式化程序

有关详细信息,请参阅复合格式设置一文中的 "处理顺序" 部分。

设置具有相同索引的项的格式

Format FormatException 如果索引项的索引大于或等于参数列表中的参数数目,则该方法将引发异常。 但是, format 只要多个格式项具有相同的索引,就可以包含比参数更多的格式项。 在以下示例中,对方法的调用中 Format(String, Object) ,参数列表具有单个参数,但格式字符串包含两个格式项:一个显示数字的十进制值,另一个显示其十六进制值。

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
Module Example
   Public Sub Main()
      Dim values() As Short = { Int16.MinValue, -27, 0, 1042, Int16.MaxValue }
      Console.WriteLine("{0,10}  {1,10}", "Decimal", "Hex")
      Console.WriteLine()
      For Each value As Short In values
         Dim formatString As String = String.Format("{0,10:G}: {0,10:X}", value)
         Console.WriteLine(formatString)
      Next        
   End Sub
End Module
' The example displays the following output:
'       Decimal         Hex
'    
'        -32768:       8000
'           -27:       FFE5
'             0:          0
'          1042:        412
'         32767:       7FFF

格式和区域性

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

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

自定义格式设置操作

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

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

示例:自定义格式设置操作

此示例定义格式提供程序,该提供程序将整数值的格式设置为 x-xxxxx-xx 形式的客户帐户号。

using namespace System;

ref class CustomerFormatter : IFormatProvider, ICustomFormatter
{
public:
   virtual Object^ GetFormat(Type^ formatType) 
   {
      if (formatType == ICustomFormatter::typeid)        
         return this; 
      else 
         return nullptr; 
   }
   
   virtual String^ Format(String^ format, 
                   Object^ arg, 
                   IFormatProvider^ formatProvider) 
   {                       
      if (! this->Equals(formatProvider))
      {
         return nullptr;
      }
      else
      {
         if (String::IsNullOrEmpty(format)) 
            format = "G";
         
         String^ customerString = arg->ToString();
         if (customerString->Length < 8)
            customerString = customerString->PadLeft(8, '0');
         
         format = format->ToUpper();
         if (format == L"G") 
               return customerString->Substring(0, 1) + "-" +
                                     customerString->Substring(1, 5) + "-" +
                                     customerString->Substring(6);
         else if (format == L"S")                          
               return customerString->Substring(0, 1) + "/" +
                                     customerString->Substring(1, 5) + "/" +
                                     customerString->Substring(6);
         else if (format == L"P")
               return customerString->Substring(0, 1) + "." +
                                     customerString->Substring(1, 5) + "." +
                                     customerString->Substring(6);
         else
               throw gcnew FormatException( 
                         String::Format("The '{0}' format specifier is not supported.", format));
         }
    }   
};

void main()
{
   int acctNumber = 79203159;
   Console::WriteLine(String::Format(gcnew CustomerFormatter, "{0}", acctNumber));
   Console::WriteLine(String::Format(gcnew CustomerFormatter, "{0:G}", acctNumber));
   Console::WriteLine(String::Format(gcnew CustomerFormatter, "{0:S}", acctNumber));
   Console::WriteLine(String::Format(gcnew CustomerFormatter, "{0:P}", acctNumber));
   try {
      Console::WriteLine(String::Format(gcnew CustomerFormatter, "{0:X}", acctNumber));
   }
   catch (FormatException^ e) {
      Console::WriteLine(e->Message);
   }
}
// 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.
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.
Module TestFormatter
   Public Sub Main()
      Dim acctNumber As Integer = 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 e As FormatException
         Console.WriteLine(e.Message)
      End Try   
   End Sub
End Module

Public Class CustomerFormatter : Implements IFormatProvider, ICustomFormatter
   Public Function GetFormat(type As Type) As Object  _
                   Implements IFormatProvider.GetFormat
      If type Is GetType(ICustomFormatter) Then
         Return Me
      Else
         Return Nothing
      End If
   End Function
   
   Public Function Format(fmt As String, _
                           arg As Object, _
                           formatProvider As IFormatProvider) As String _
                    Implements ICustomFormatter.Format
      If Not Me.Equals(formatProvider) Then
         Return Nothing
      Else
         If String.IsNullOrEmpty(fmt) Then fmt = "G"
         
         Dim customerString As String = arg.ToString()
         if customerString.Length < 8 Then _
            customerString = customerString.PadLeft(8, "0"c)
         
         Select Case fmt
            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)
            Case Else
               Throw New FormatException( _
                         String.Format("The '{0}' format specifier is not supported.", fmt))
         End Select                                                     
      End If   
   End Function
End Class
' 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 namespace System;
using namespace System::Globalization;

ref class InterceptProvider : IFormatProvider, ICustomFormatter
{
public:
   virtual Object^ GetFormat(Type^ formatType)
   {
      if (formatType == ICustomFormatter::typeid)   
         return this;
      else
         return nullptr;
   }
   
   virtual String^ Format(String^ format, Object^ obj, IFormatProvider^ provider) 
   {
      // Display information about method call.
      String^ formatString = format != nullptr ? format : "<null>";
      Console::WriteLine("Provider: {0}, Object: {1}, Format String: {2}",
                        provider, obj != nullptr ? obj : "<null>", formatString);
                        
      if (obj == nullptr) return String::Empty;
            
      // If this is a byte and the "R" format string, format it with Roman numerals.
      if (obj->GetType() == Byte::typeid && 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, remainder);
         if (result > 0)  
            returnString = gcnew String('C', result);
         value = (Byte) remainder;
         // Get the 50s digit
         result = Math::DivRem(value, 50, remainder);
         if (result == 1)
            returnString += "L";
         value = (Byte) remainder;
         // Get the tens digit.
         result = Math::DivRem(value, 10, remainder);
         if (result > 0)
            returnString += gcnew String('X', result);
         value = (Byte) remainder; 
         // Get the fives digit.
         result = Math::DivRem(value, 5, remainder);
         if (result > 0)
            returnString += "V";
         value = (Byte) remainder;
         // Add the ones digit.
         if (remainder > 0) 
            returnString += gcnew 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->GetType() == IFormattable::typeid)
         return ((IFormattable^) obj)->ToString(format, CultureInfo::CurrentCulture);
      else
         return obj->ToString();
   }
};

void main()
{
   int n = 10;
   double value = 16.935;
   DateTime day = DateTime::Now;
   InterceptProvider^ provider = gcnew 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
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.GetType().Name, 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
Imports System.Globalization

Public Class InterceptProvider : Implements IFormatProvider, ICustomFormatter
   Public Function GetFormat(formatType As Type) As Object _
         Implements IFormatProvider.GetFormat
      If formatType Is GetType(ICustomFormatter) Then
         Return Me
      Else
         Return Nothing
      End If
   End Function
   
   Public Function Format(fmt As String, obj As Object, provider As IFormatProvider) As String _
         Implements ICustomFormatter.Format

      Dim formatString As String = If(fmt IsNot Nothing, fmt, "<null>")
      Console.WriteLine("Provider: {0}, Object: {1}, Format String: {2}",
                        provider, If(obj IsNot Nothing, obj, "<null>"), formatString)

      If obj Is Nothing Then Return String.Empty
            
      ' If this is a byte and the "R" format string, format it with Roman numerals.
      If TypeOf(obj) Is Byte AndAlso formatString.ToUpper.Equals("R") Then
         Dim value As Byte = CByte(obj)
         Dim remainder As Integer
         Dim result As Integer
         Dim returnString As String = String.Empty

         ' Get the hundreds digit(s)
         result = Math.DivRem(value, 100, remainder)
         If result > 0 Then returnString = New String("C"c, result)
         value = CByte(remainder)
         ' Get the 50s digit
         result = Math.DivRem(value, 50, remainder)
         If result = 1 Then returnString += "L"
         value = CByte(remainder)
         ' Get the tens digit.
         result = Math.DivRem(value, 10, remainder)
         If result > 0 Then returnString += New String("X"c, result)
         value = CByte(remainder) 
         ' Get the fives digit.
         result = Math.DivRem(value, 5, remainder)
         If result > 0 Then returnString += "V"
         value = CByte(remainder)
         ' Add the ones digit.
         If remainder > 0 Then returnString += New String("I"c, remainder)
         
         ' Check whether we have too many X characters.
         Dim pos As Integer = returnString.IndexOf("XXXX")
         If pos >= 0 Then
            Dim xPos As Integer = returnString.IndexOf("L") 
            If xPos >= 0 And xPos = pos - 1 Then
               returnString = returnString.Replace("LXXXX", "XC")
            Else
               returnString = returnString.Replace("XXXX", "XL")   
            End If         
         End If
         ' Check whether we have too many I characters
         pos = returnString.IndexOf("IIII")
         If pos >= 0 Then
            If returnString.IndexOf("V") >= 0 Then
               returnString = returnString.Replace("VIIII", "IX")
            Else
               returnString = returnString.Replace("IIII", "IV")    
            End If
         End If
         Return returnString 
      End If   

      ' Use default for all other formatting.
      If obj Is GetType(IFormattable)
         Return CType(obj, IFormattable).ToString(fmt, CultureInfo.CurrentCulture)
      Else
         Return obj.ToString()
      End If
   End Function
End Class

Module Example
   Public Sub Main()
      Dim n As Integer = 10
      Dim value As Double = 16.935
      Dim day As DateTime = Date.Now
      Dim provider As New InterceptProvider()
      Console.WriteLine(String.Format(provider, "{0:N0}: {1:C2} on {2:d}", n, value, day))
      Console.WriteLine()
      Console.WriteLine(String.Format(provider, "{0}: {1:F}", "Today", 
                                      CType(Date.Now.DayOfWeek, DayOfWeek)))
      Console.WriteLine()
      Console.WriteLine(String.Format(provider, "{0:X}, {1}, {2}\n", 
                                      CByte(2), CByte(12), CByte(199)))
      Console.WriteLine()
      Console.WriteLine(String.Format(provider, "{0:R}, {1:R}, {2:R}", 
                                      CByte(2), CByte(12), CByte(199)))
   End Sub
End Module
' 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

字符串格式 Q &

为什么建议通过调用方法来插入字符串 String.Format

字符串内插为:

  • 更灵活。 它可用于任何字符串,无需调用支持复合格式设置的方法。 否则,必须调用 Format 方法或支持复合格式设置的其他方法,如 Console.WriteLineStringBuilder.AppendFormat

  • 可读性更强。 由于插入到字符串中的表达式出现在内插表达式中(而不是自变量列表中),因此,内插字符串的代码和读取更为容易。 由于其可读性更高,内插字符串不仅可以替换对复合格式方法的调用,还可以在字符串串联操作中使用,以生成更简洁简洁的代码。

下面两个代码示例的比较说明了经营字符串连接和对复合格式设置方法的调用的内插字符串。 在下面的示例中,使用多个字符串串联操作会生成详细的代码和难于阅读的代码。

  string[] names = { "Balto", "Vanya", "Dakota", "Samuel", "Koani", "Yiska", "Yuma" };
  string output = names[0] + ", " + names[1] + ", " + names[2] + ", " + 
                  names[3] + ", " + names[4] + ", " + names[5] + ", " + 
                  names[6];  

  output += "\n";  
  var date = DateTime.Now;
  output += String.Format("It is {0:t} on {0:d}. The day of the week is {1}.", 
                          date, date.DayOfWeek);
  Console.WriteLine(output);                           
  // The example displays the following output:
  //     Balto, Vanya, Dakota, Samuel, Koani, Yiska, Yuma
  //     It is 10:29 AM on 1/8/2018. The day of the week is Monday.

Module Example
   Public Sub Main()
      Dim names = { "Balto", "Vanya", "Dakota", "Samuel", "Koani", "Yiska", "Yuma" }
      Dim output = names(0) + ", " + names(1) + ", " + names(2) + ", " + 
                   names(3) + ", " + names(4) + ", " + names(5) + ", " + 
                   names(6)  
    
      output += vbCrLf  
      Dim dat = DateTime.Now
      output += String.Format("It is {0:t} on {0:d}. The day of the week is {1}.", 
                              dat, dat.DayOfWeek)
      Console.WriteLine(output)                           
   End Sub
End Module
' The example displays the following output:
'     Balto, Vanya, Dakota, Samuel, Koani, Yiska, Yuma
'     It is 10:29 AM on 1/8/2018. The day of the week is Monday.

与此相反,在下面的示例中使用内插字符串会生成比字符串串联语句更清晰、更简洁的代码,并对 Format 上一示例中的方法进行调用。

  string[] names = { "Balto", "Vanya", "Dakota", "Samuel", "Koani", "Yiska", "Yuma" };
  string output = $"{names[0]}, {names[1]}, {names[2]}, {names[3]}, {names[4]}, " + 
                  $"{names[5]}, {names[6]}";  

  var date = DateTime.Now;
  output += $"\nIt is {date:t} on {date:d}. The day of the week is {date.DayOfWeek}.";
  Console.WriteLine(output);                           
  // The example displays the following output:
  //     Balto, Vanya, Dakota, Samuel, Koani, Yiska, Yuma
  //     It is 10:29 AM on 1/8/2018. The day of the week is Monday.

Module Example
   Public Sub Main()
      Dim names = { "Balto", "Vanya", "Dakota", "Samuel", "Koani", "Yiska", "Yuma" }
      Dim output = $"{names(0)}, {names(1)}, {names(2)}, {names(3)}, {names(4)}, " + 
                   $"{names(5)}, {names(6)}"  
    
      Dim dat = DateTime.Now
      output += $"{vbCrLf}It is {dat:t} on {dat:d}. The day of the week is {dat.DayOfWeek}." 
      Console.WriteLine(output)                           
   End Sub
End Module
' The example displays the following output:
'     Balto, Vanya, Dakota, Samuel, Koani, Yiska, Yuma
'     It is 10:29 AM on 1/8/2018. The day of the week is Monday.

在哪里可以找到可用于格式项的预定义格式字符串列表?

如何实现控制替换格式项的结果字符串的对齐方式吗?

格式项的一般语法为:

{index[,alignment][: formatString]}

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

如何实现控制小数点分隔符后的位数?

除 "D" (之外的所有 标准数字格式字符串 (仅适用于整数) "G"、"R" 和 "X")都允许使用精度说明符定义结果字符串中的小数位数。 下面的示例使用标准数字格式字符串来控制结果字符串中的小数位数。

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 output like the following:
//       $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 %
Module Example
   Public Sub Main()
      Dim values() As Object = { 1603, 1794.68235, 15436.14 }
      Dim result As String
      For Each value In values
         result = String.Format("{0,12:C2}   {0,12:E3}   {0,12:F4}   {0,12:N3}  {1,12:P2}",
                                value, CDbl(value) / 10000)
         Console.WriteLine(result) 
         Console.WriteLine()
      Next                             
   End Sub
End Module
' 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" 格式说明符控制结果字符串中的小数位数,如下面的示例所示。

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
Module Example
   Public Sub Main()
      Dim value As Decimal = 16309.5436d
      Dim result As String = String.Format("{0,12:#.00000} {0,12:0,000.00} {0,12:000.00#}", 
                                           value)
      Console.WriteLine(result)
   End Sub
End Module
' The example displays the following output:
'    16309.54360    16,309.54    16309.544

如何实现控制整数位数?

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

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
Module Example
   Public Sub Main()
      Dim value As Integer = 1326
      Dim result As String = String.Format("{0,10:D6} {0,10:X8}", value)
      Console.WriteLine(result)
   End Sub
End Module
' The example displays the following output:
'       001326   0000052E

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

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
Module Example
   Public Sub Main()
      Dim value As Integer = 16342
      Dim result As String = String.Format("{0,18:00000000} {0,18:00000000.000} {0,18:000,0000,000.0}", 
                                           value)
      Console.WriteLine(result)
   End Sub
End Module
' 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)

单个左大括号或右大括号始终解释为格式项的开头或结尾。 若要按原义解释,则必须对其进行转义。 通过添加另一个大括号 ( "{{" 和 "}}" 而不是 "{" 和 "}" ) 来转义大括号,如以下方法调用所示:

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

不过,甚至可以轻松地误解转义大括号。 建议在格式列表中包含大括号,并使用格式项将它们插入到结果字符串中,如下面的示例所示。

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

为什么调用字符串。 Format 方法会引发 FormatException?

出现异常的最常见原因是格式项的索引与格式列表中的对象不对应。 通常,这表示格式项的索引编号错误,或者忘记在格式列表中包含对象。 尝试包含未转义的左大括号或右大括号字符也会引发 FormatException 。 有时,异常是拼写错误的结果;例如,一个典型的错误是,在左括号 (键入"[") 而不是左大括号 ("{") 。

如果 Format (System.IFormatProvider,System.String,System.Object[]) 方法支持参数数组,为什么我的代码在使用数组时引发异常?

例如,以下代码引发 FormatException 异常:

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);
Imports System.Collections.Generic

Module Example
   Public Sub Main()
      Dim rnd As New Random()
      Dim numbers(3) As Integer
      Dim total As Integer = 0
      For ctr = 0 To 2
         Dim number As Integer = rnd.Next(1001)
         numbers(ctr) = number
         total += number
      Next
      numbers(3) = total
      Console.WriteLine("{0} + {1} + {2} = {3}", numbers)   
   End Sub
End Module

这是编译器重载解析的问题。 由于编译器无法将整数数组转换为对象数组,因此它将整数数组视为单个参数,因此它调用 Format(String, Object) 方法。 引发异常的原因是有四个格式项,但格式列表中只有一个项。

由于 Visual Basic 和 C# 均不能将整数数组转换为对象数组,因此在调用 方法之前,必须自己执行 Format(String, Object[]) 转换。 以下示例提供了一个实现。

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);
Imports System.Collections.Generic

Module Example
   Public Sub Main()
      Dim rnd As New Random()
      Dim numbers(3) As Integer
      Dim total As Integer = 0
      For ctr = 0 To 2
         Dim number As Integer = rnd.Next(1001)
         numbers(ctr) = number
         total += number
      Next
      numbers(3) = total
      Dim values(numbers.Length - 1) As Object
      numbers.CopyTo(values, 0) 
      Console.WriteLine("{0} + {1} + {2} = {3}", values)   
   End Sub
End Module

Format(String, Object)

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

public:
 static System::String ^ Format(System::String ^ format, System::Object ^ arg0);
public static string Format (string format, object arg0);
public static string Format (string format, object? arg0);
static member Format : string * obj -> string
Public Shared Function Format (format As String, arg0 As Object) As String

参数

arg0
Object

要设置格式的对象。

返回

String

format 的副本,其中的任何格式项均替换为 arg0 的字符串表示形式。

例外

format 上声明的默认值为 null

format 中的格式项无效。

  • 或 -

格式项的索引不为零。

注解

重要

可以不调用 String.Format 方法或使用复合格式字符串,而改为使用内插字符串(如果受语言支持的话)。 内插字符串是包含内插表达式的字符串。 每个内插表达式都使用表达式的值进行解析,并在分配字符串时包含在结果字符串中。 有关详细信息,请参阅字符串内插(C# 参考)内插字符串(Visual Basic 参考)

此方法使用 复合格式设置功能 将表达式的值转换为其字符串表示形式,并将该表示形式嵌入字符串中。

但是,在调用 String.Format 方法时,不需要关注需要调用的特定重载。 相反,可以借助包括一个或多个格式项的复合格式字符串调用方法。 为每个格式项分配一个数字索引;第一个索引从 0 开始。 除了初始字符串,方法调用拥有的额外参数数应该与其拥有的索引值数相同。 例如,格式项有 0 和 1 两个索引的字符串应该有 2 个参数;索引为 0 到 5 的字符串应该有 6 个参数。 然后,你的语言编译器将会将方法调用解析为 String.Format 方法的特定重载。

有关使用 String.Format 方法的详细文档,请参阅 String.Format 方法入门我调用哪个方法?

示例:设置单个参数的格式

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

using namespace System;

void main()
{
   DateTime birthdate = DateTime(1993, 7, 28);
   array<DateTime>^ dates = gcnew array<DateTime> { DateTime(1993, 8, 16), 
                                                    DateTime(1994, 7, 28), 
                                                    DateTime(2000, 10, 16), 
                                                    DateTime(2003, 7, 27), 
                                                    DateTime(2007, 5, 27) };

   for each (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.
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.
Module Example
   Public Sub Main()
      Dim birthdate As Date = #7/28/1993#
      Dim dates() As Date = { #9/16/1993#, #7/28/1994#, #10/16/2000#, _
                              #7/27/2003#, #5/27/2007# }
      For Each dateValue As Date In dates
         Dim interval As TimeSpan = dateValue - birthdate
         ' Get the approximate number of years, without accounting for leap years.
         Dim years As Integer = CInt(interval.TotalDays) \ 365
         ' See if adding the number of years exceeds dateValue.
         Dim output As String
         If birthdate.AddYears(years) <= dateValue Then
            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)   
         End If
      Next
   End Sub
End Module
' 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[])

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

public:
 static System::String ^ Format(System::String ^ format, ... cli::array <System::Object ^> ^ args);
public static string Format (string format, params object[] args);
public static string Format (string format, params object?[] args);
static member Format : string * obj[] -> string
Public Shared Function Format (format As String, ParamArray args As Object()) As String

参数

args
Object[]

一个对象数组,其中包含零个或多个要设置格式的对象。

返回

String

format 的副本,其中格式项已替换为 args 中相应对象的字符串表示形式。

例外

formatargsnull

format 无效。

  • 或 -

格式项的索引小于零,或者大于或等于 args 数组的长度。

注解

重要

可以不调用 String.Format 方法或使用复合格式字符串,而改为使用内插字符串(如果受语言支持的话)。 内插字符串是包含内插表达式的字符串。 每个内插表达式都使用表达式的值进行解析,并在分配字符串时包含在结果字符串中。 有关详细信息,请参阅字符串内插(C# 参考)内插字符串(Visual Basic 参考)

此方法使用 复合格式设置 功能将四个或多个表达式的值转换为其字符串表示形式,并将这些表示形式嵌入字符串中。 由于 args 参数标有 特性,因此可以将对象作为单个参数或作为数组 System.ParamArrayAttribute 传递给 Object 方法。

但是,在调用 String.Format 方法时,不需要关注需要调用的特定重载。 相反,可以借助包括一个或多个格式项的复合格式字符串调用方法。 为每个格式项分配一个数字索引;第一个索引从 0 开始。 除了初始字符串,方法调用拥有的额外参数数应该与其拥有的索引值数相同。 例如,格式项有 0 和 1 两个索引的字符串应该有 2 个参数;索引为 0 到 5 的字符串应该有 6 个参数。 然后,你的语言编译器将会将方法调用解析为 String.Format 方法的特定重载。

有关使用 String.Format 方法的详细文档,请参阅 String.Format 方法入门我调用哪个方法?

示例:设置三多个参数的格式

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

using namespace System;

void main()
{
   DateTime date1 = DateTime(2009, 7, 1);
   TimeSpan hiTime = TimeSpan(14, 17, 32);
   Decimal hiTemp = (Decimal) 62.1; 
   TimeSpan loTime = TimeSpan(3, 16, 10);
   Decimal loTemp = (Decimal)54.8; 

   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)", 
                                    gcnew array<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)
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 output like the following:
//       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)
Module Example
   Public Sub Main()
      Dim date1 As Date = #7/1/2009#
      Dim hiTime As New TimeSpan(14, 17, 32)
      Dim hiTemp As Decimal = 62.1d 
      Dim loTime As New TimeSpan(3, 16, 10)
      Dim loTemp As Decimal = 54.8d 

      Dim result1 As String = String.Format("Temperature on {0:d}:{5}{1,11}: {2} degrees (hi){5}{3,11}: {4} degrees (lo)", _
                                           date1, hiTime, hiTemp, loTime, loTemp, vbCrLf)
      Console.WriteLine(result1)
      Console.WriteLine()
           
      Dim result2 As String = String.Format("Temperature on {0:d}:{5}{1,11}: {2} degrees (hi){5}{3,11}: {4} degrees (lo)", _
                                            New Object() { date1, hiTime, hiTemp, loTime, loTemp, vbCrLf })
      Console.WriteLine(result2)                                            
   End Sub
End Module
' 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 namespace System;

ref class CityInfo
{
public:
   CityInfo(String^ name, int population, Decimal area, int year)
   {
      this->Name = name;
      this->Population = population;
      this->Area = area;
      this->Year = year;
   }
   
   String^ Name; 
   int Population;
   Decimal Area;
   int Year;
};

ref class Example
{
public:
   static void ShowPopulationData(CityInfo^ city)
   {
      array<Object^>^ args = gcnew array<Object^> { 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); 
   }
};

void main()
{
   CityInfo^ nyc2010 = gcnew CityInfo("New York", 8175133, (Decimal) 302.64, 2010);
   Example::ShowPopulationData(nyc2010);
   CityInfo^ sea2010 = gcnew CityInfo("Seattle", 608660, (Decimal) 83.94, 2010);      
   Example::ShowPopulationData(sea2010); 
}
// 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
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
Public Class CityInfo
   Public Sub New(name As String, population As Integer, area As Decimal, year As Integer)
      Me.Name = name
      Me.Population = population
      Me.Area = area
      Me.Year = year
   End Sub
   
   Public ReadOnly Name As String
   Public ReadOnly Population As Integer
   Public ReadOnly Area As Decimal
   Public ReadOnly Year As Integer
End Class

Module Example
   Public Sub Main()
      Dim nyc2010 As New CityInfo("New York", 8175133, 302.64d, 2010)
      ShowPopulationData(nyc2010)
      Dim sea2010 As New CityInfo("Seattle", 608660, 83.94d, 2010)      
      ShowPopulationData(sea2010) 
   End Sub
   
   Private Sub ShowPopulationData(city As CityInfo)
      Dim args() As Object = { city.Name, city.Year, city.Population, city.Area }
      Dim result = String.Format("{0} in {1}: Population {2:N0}, Area {3:N1} sq. feet", args)
      Console.WriteLine(result) 
   End Sub
End Module
' 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)

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

public:
 static System::String ^ Format(IFormatProvider ^ provider, System::String ^ format, System::Object ^ arg0);
public static string Format (IFormatProvider provider, string format, object arg0);
public static string Format (IFormatProvider? provider, string format, object? arg0);
static member Format : IFormatProvider * string * obj -> string
Public Shared Function Format (provider As IFormatProvider, format As String, arg0 As Object) As String

参数

provider
IFormatProvider

一个提供区域性特定的格式设置信息的对象。

arg0
Object

要设置格式的对象。

返回

String

format 的副本,其中的一个或多个格式项已替换为 arg0 的字符串表示形式。

例外

format 上声明的默认值为 null

format 无效。

  • 或 -

格式项的索引不为零。

注解

重要

可以不调用 String.Format 方法或使用复合格式字符串,而改为使用内插字符串(如果受语言支持的话)。 内插字符串是包含内插表达式的字符串。 每个内插表达式都使用表达式的值进行解析,并在分配字符串时包含在结果字符串中。 有关详细信息,请参阅字符串内插(C# 参考)内插字符串(Visual Basic 参考)

此方法使用 复合格式设置功能 将表达式的值转换为其字符串表示形式,并将该表示形式嵌入字符串中。 在执行转换时, 方法使用区分区域性的格式设置或自定义格式化程序。 方法 arg0 通过调用其 ToString (IFormatProvider) 方法转换为其字符串表示形式;如果对象的相应格式项包含格式字符串,则通过调用其 ToString (String,IFormatProvider) 方法。 如果这些方法不存在,它将调用对象的无参数 ToString 方法。

但是,在调用 String.Format 方法时,不需要关注需要调用的特定重载。 相反,可以使用提供区分区域性或自定义格式设置的对象和包含一个或多个格式项的复合格式字符串来调用此方法。 为每个格式项分配一个数字索引;第一个索引从 0 开始。 除了初始字符串,方法调用拥有的额外参数数应该与其拥有的索引值数相同。 例如,格式项有 0 和 1 两个索引的字符串应该有 2 个参数;索引为 0 到 5 的字符串应该有 6 个参数。 然后,你的语言编译器将会将方法调用解析为 String.Format 方法的特定重载。

有关使用 String.Format 方法的详细文档,请参阅 String.Format 方法入门我调用哪个方法?

适用于

Format(IFormatProvider, String, Object[])

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

public:
 static System::String ^ Format(IFormatProvider ^ provider, System::String ^ format, ... cli::array <System::Object ^> ^ args);
public static string Format (IFormatProvider provider, string format, params object[] args);
public static string Format (IFormatProvider? provider, string format, params object?[] args);
static member Format : IFormatProvider * string * obj[] -> string
Public Shared Function Format (provider As IFormatProvider, format As String, ParamArray args As Object()) As String

参数

provider
IFormatProvider

一个提供区域性特定的格式设置信息的对象。

args
Object[]

一个对象数组,其中包含零个或多个要设置格式的对象。

返回

String

format 的副本,其中格式项已替换为 args 中相应对象的字符串表示形式。

例外

formatargsnull

format 无效。

  • 或 -

格式项的索引小于零,或者大于或等于 args 数组的长度。

注解

重要

可以不调用 String.Format 方法或使用复合格式字符串,而改为使用内插字符串(如果受语言支持的话)。 内插字符串是包含内插表达式的字符串。 每个内插表达式都使用表达式的值进行解析,并在分配字符串时包含在结果字符串中。 有关详细信息,请参阅字符串内插(C# 参考)内插字符串(Visual Basic 参考)

此方法使用 复合格式设置功能 将四个或多个表达式转换为其字符串表示形式,并将这些表示形式嵌入字符串中。 在执行转换时, 方法使用区分区域性的格式设置或自定义格式化程序。 方法通过调用其 Object ToString (IFormatProvider) 方法,或者,如果对象的对应格式项包含格式字符串,则通过调用其 ToString (String,IFormatProvider) 方法,将每个参数转换为其字符串表示形式。 如果这些方法不存在,它将调用对象的无参数 ToString 方法。

但是,在调用 String.Format 方法时,不需要关注需要调用的特定重载。 相反,可以使用提供区分区域性或自定义格式设置的对象和包含一个或多个格式项的复合格式字符串来调用此方法。 为每个格式项分配一个数字索引;第一个索引从 0 开始。 除了初始字符串,方法调用拥有的额外参数数应该与其拥有的索引值数相同。 例如,格式项有 0 和 1 两个索引的字符串应该有 2 个参数;索引为 0 到 5 的字符串应该有 6 个参数。 然后,你的语言编译器将会将方法调用解析为 String.Format 方法的特定重载。

有关使用 String.Format 方法的详细文档,请参阅 String.Format 方法入门我调用哪个方法?

示例:区分区域性的格式设置

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

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)
{
   System.Globalization.CultureInfo culture = new System.Globalization.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
Imports System.Globalization

Module Example
   Public Sub Main()
      Dim cultureNames() As String = { "en-US", "fr-FR", "de-DE", "es-ES" }
      
      Dim dateToDisplay As Date = #9/1/2009 6:32PM#
      Dim value As Double = 9164.32

      Console.WriteLine("Culture     Date                                Value")
      Console.WriteLine()      
      For Each cultureName As String In cultureNames
         Dim culture As New CultureInfo(cultureName)
         Dim output As String = String.Format(culture, "{0,-11} {1,-35:D} {2:N}", _
                                              culture.Name, dateToDisplay, value)
         Console.WriteLine(output)
      Next    
   End Sub
End Module
' 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

另请参阅

适用于

Format(String, Object, Object)

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

public:
 static System::String ^ Format(System::String ^ format, System::Object ^ arg0, System::Object ^ arg1);
public static string Format (string format, object arg0, object arg1);
public static string Format (string format, object? arg0, object? arg1);
static member Format : string * obj * obj -> string
Public Shared Function Format (format As String, arg0 As Object, arg1 As Object) As String

参数

arg0
Object

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

arg1
Object

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

返回

String

format 的副本,其中的格式项替换为 arg0arg1 的字符串表示形式。

例外

format 上声明的默认值为 null

format 无效。

  • 或 -

格式项的索引不为零或一。

注解

重要

可以不调用 String.Format 方法或使用复合格式字符串,而改为使用内插字符串(如果受语言支持的话)。 内插字符串是包含内插表达式的字符串。 每个内插表达式都使用表达式的值进行解析,并在分配字符串时包含在结果字符串中。 有关详细信息,请参阅字符串内插(C# 参考)内插字符串(Visual Basic 参考)

此方法使用 复合格式设置功能 将两个表达式的值转换为其字符串表示形式,并将这些表示形式嵌入字符串中。

但是,在调用 String.Format 方法时,不需要关注需要调用的特定重载。 相反,可以借助包括一个或多个格式项的复合格式字符串调用方法。 为每个格式项分配一个数字索引;第一个索引从 0 开始。 除了初始字符串,方法调用拥有的额外参数数应该与其拥有的索引值数相同。 例如,格式项有 0 和 1 两个索引的字符串应该有 2 个参数;索引为 0 到 5 的字符串应该有 6 个参数。 然后,你的语言编译器将会将方法调用解析为 String.Format 方法的特定重载。

有关使用 String.Format 方法的详细文档,请参阅 String.Format 方法入门我调用哪个方法?

示例:设置两个参数的格式

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

using namespace System;
using namespace System::Collections::Generic;

void main()
{
   Dictionary<DateTime, Double>^ temperatureInfo = gcnew Dictionary<DateTime, Double>(); 
   temperatureInfo->Add(DateTime(2010, 6, 1, 14, 0, 0), 87.46);
   temperatureInfo->Add(DateTime(2010, 12, 1, 10, 0, 0), 36.81);
      
   Console::WriteLine("Temperature Information:\n");
   String^ output;   
   for each (KeyValuePair<DateTime, Double>^ 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
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 output like the following:
//       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
Imports System.Collections.Generic

Module Example
   Public Sub Main()
      Dim temperatureInfo As New Dictionary(Of Date, Double) 
      temperatureInfo.Add(#6/1/2010 2:00PM#, 87.46)
      temperatureInfo.Add(#12/1/2010 10:00AM#, 36.81)
      
      Console.WriteLine("Temperature Information:")
      Console.WriteLine()
      Dim output As String   
      For Each 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)
      Next
   End Sub
End Module
' 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(IFormatProvider, String, Object, Object)

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

public:
 static System::String ^ Format(IFormatProvider ^ provider, System::String ^ format, System::Object ^ arg0, System::Object ^ arg1);
public static string Format (IFormatProvider provider, string format, object arg0, object arg1);
public static string Format (IFormatProvider? provider, string format, object? arg0, object? arg1);
static member Format : IFormatProvider * string * obj * obj -> string
Public Shared Function Format (provider As IFormatProvider, format As String, arg0 As Object, arg1 As Object) As String

参数

provider
IFormatProvider

一个提供区域性特定的格式设置信息的对象。

arg0
Object

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

arg1
Object

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

返回

String

format 的副本,其中的格式项替换为 arg0arg1 的字符串表示形式。

例外

format 上声明的默认值为 null

format 无效。

  • 或 -

格式项的索引不为零或一。

注解

重要

可以不调用 String.Format 方法或使用复合格式字符串,而改为使用内插字符串(如果受语言支持的话)。 内插字符串是包含内插表达式的字符串。 每个内插表达式都使用表达式的值进行解析,并在分配字符串时包含在结果字符串中。 有关详细信息,请参阅字符串内插(C# 参考)内插字符串(Visual Basic 参考)

此方法使用 复合格式设置功能 将两个表达式转换为其字符串表示形式,并将这些表示形式嵌入字符串中。 在执行转换时, 方法使用区分区域性的格式设置或自定义格式化程序。 方法通过调用其 Object ToString (IFormatProvider) 方法,或者,如果对象的对应格式项包含格式字符串,则通过调用其 ToString (String,IFormatProvider) 方法,将每个参数转换为其字符串表示形式。 如果这些方法不存在,它将调用对象的无参数 ToString 方法。

但是,在调用 String.Format 方法时,不需要关注需要调用的特定重载。 相反,可以使用提供区分区域性或自定义格式设置的对象和包含一个或多个格式项的复合格式字符串来调用此方法。 为每个格式项分配一个数字索引;第一个索引从 0 开始。 除了初始字符串,方法调用拥有的额外参数数应该与其拥有的索引值数相同。 例如,格式项有 0 和 1 两个索引的字符串应该有 2 个参数;索引为 0 到 5 的字符串应该有 6 个参数。 然后,你的语言编译器将会将方法调用解析为 String.Format 方法的特定重载。

有关使用 String.Format 方法的详细文档,请参阅 String.Format 方法入门我调用哪个方法?

适用于

Format(String, Object, Object, Object)

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

public:
 static System::String ^ Format(System::String ^ format, System::Object ^ arg0, System::Object ^ arg1, System::Object ^ arg2);
public static string Format (string format, object arg0, object arg1, object arg2);
public static string Format (string format, object? arg0, object? arg1, object? arg2);
static member Format : string * obj * obj * obj -> string
Public Shared Function Format (format As String, arg0 As Object, arg1 As Object, arg2 As Object) As String

参数

arg0
Object

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

arg1
Object

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

arg2
Object

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

返回

String

format 的副本,其中的格式项已替换为 arg0arg1arg2 的字符串表示形式。

例外

format 上声明的默认值为 null

format 无效。

  • 或 -

格式项的索引小于零,或者大于二。

注解

重要

可以不调用 String.Format 方法或使用复合格式字符串,而改为使用内插字符串(如果受语言支持的话)。 内插字符串是包含内插表达式的字符串。 每个内插表达式都使用表达式的值进行解析,并在分配字符串时包含在结果字符串中。 有关详细信息,请参阅字符串内插(C# 参考)内插字符串(Visual Basic 参考)

此方法使用 复合格式设置功能 将三个表达式的值转换为其字符串表示形式,并将这些表示形式嵌入字符串中。

但是,在调用 String.Format 方法时,不需要关注需要调用的特定重载。 相反,可以借助包括一个或多个格式项的复合格式字符串调用方法。 为每个格式项分配一个数字索引;第一个索引从 0 开始。 除了初始字符串,方法调用拥有的额外参数数应该与其拥有的索引值数相同。 例如,格式项有 0 和 1 两个索引的字符串应该有 2 个参数;索引为 0 到 5 的字符串应该有 6 个参数。 然后,你的语言编译器将会将方法调用解析为 String.Format 方法的特定重载。

有关使用 String.Format 方法的详细文档,请参阅 String.Format 方法入门我调用哪个方法?

示例:设置三个参数的格式

此示例使用 Format(String, Object, Object, Object) 方法创建一个字符串,该字符串演示具有两个整数值的布尔 And 运算的结果。 请注意,格式字符串包含六个格式项,但方法的参数列表中只有三个项,因为每个项的格式都采用两种不同的方式。

using namespace System;

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)
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)
Public Module Example
   Public Sub Main()
      Dim formatString As String = "    {0,10} ({0,8:X8})" + vbCrLf +  _
                                   "And {1,10} ({1,8:X8})" + vbCrLf + _
                                   "  = {2,10} ({2,8:X8})"
      Dim value1 As Integer = 16932
      Dim value2 As Integer = 15421
      Dim result As String = String.Format(formatString, _
                                           value1, value2, value1 And value2)
      Console.WriteLine(result)                          
   End Sub
End Module
' The example displays the following output:
'                16932 (00004224)
'       And      15421 (00003C3D)
'         =         36 (00000024)

另请参阅

适用于

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

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

public:
 static System::String ^ Format(IFormatProvider ^ provider, System::String ^ format, System::Object ^ arg0, System::Object ^ arg1, System::Object ^ arg2);
public static string Format (IFormatProvider provider, string format, object arg0, object arg1, object arg2);
public static string Format (IFormatProvider? provider, string format, object? arg0, object? arg1, object? arg2);
static member Format : IFormatProvider * string * obj * obj * obj -> string
Public Shared Function Format (provider As IFormatProvider, format As String, arg0 As Object, arg1 As Object, arg2 As Object) As String

参数

provider
IFormatProvider

一个提供区域性特定的格式设置信息的对象。

arg0
Object

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

arg1
Object

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

arg2
Object

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

返回

String

format 的副本,其中的格式项已替换为 arg0arg1arg2 的字符串表示形式。

例外

format 上声明的默认值为 null

format 无效。

  • 或 -

格式项的索引小于零,或者大于二。

注解

重要

可以不调用 String.Format 方法或使用复合格式字符串,而改为使用内插字符串(如果受语言支持的话)。 内插字符串是包含内插表达式的字符串。 每个内插表达式都使用表达式的值进行解析,并在分配字符串时包含在结果字符串中。 有关详细信息,请参阅字符串内插(C# 参考)内插字符串(Visual Basic 参考)

此方法使用 复合格式设置功能 将三个表达式转换为其字符串表示形式,并将这些表示形式嵌入字符串中。 在执行转换时, 方法使用区分区域性的格式设置或自定义格式化程序。 方法通过调用其 Object ToString (IFormatProvider) 方法,或者,如果对象的对应格式项包含格式字符串,则通过调用其 ToString (String,IFormatProvider) 方法,将每个参数转换为其字符串表示形式。 如果这些方法不存在,它将调用对象的无参数 ToString 方法。

但是,在调用 String.Format 方法时,不需要关注需要调用的特定重载。 相反,可以使用提供区分区域性或自定义格式设置的对象和包含一个或多个格式项的复合格式字符串来调用此方法。 为每个格式项分配一个数字索引;第一个索引从 0 开始。 除了初始字符串,方法调用拥有的额外参数数应该与其拥有的索引值数相同。 例如,格式项有 0 和 1 两个索引的字符串应该有 2 个参数;索引为 0 到 5 的字符串应该有 6 个参数。 然后,你的语言编译器将会将方法调用解析为 String.Format 方法的特定重载。

有关使用 String.Format 方法的详细文档,请参阅 String.Format 方法入门我调用哪个方法?

适用于