複合格式Composite Formatting

.NET 複合格式功能會採用物件清單和複合格式字串作為輸入。The .NET composite formatting feature takes a list of objects and a composite format string as input. 複合格式字串是由混合索引替代符號 (Placeholder) 的固定文字所組成 (這些符號稱為對應至清單內物件的格式項目)。A composite format string consists of fixed text intermixed with indexed placeholders, called format items, that correspond to the objects in the list. 格式作業產生的結果字串是由原始固定文字所組成,這些固定文字混合了清單中代表物件的字串。The formatting operation yields a result string that consists of the original fixed text intermixed with the string representation of the objects in the list.

重要

如果您使用的語言和語言版本支援,您可以使用「內插字串」,而不使用複合格式字串。Instead of using composite format strings, you can use interpolated strings if the language and language version that you're using support them. 內插字串是包含「插入運算式」的字串。An interpolated string is a string that contains interpolated expressions. 每個插值的運算式會以運算式的值解析,且在字串指派時,包含在結果字串中。Each interpolated expression is resolved with the expression's value and included in the result string when the string is assigned. 如需詳細資訊,請參閱字串內插補點 (C# 參考)字串內插補點 (Visual Basic 參考)For more information, see String interpolation (C# Reference) and Interpolated strings (Visual Basic Reference).

下列方法支援複合格式功能:The composite formatting feature is supported by methods such as the following:

複合格式字串Composite Format String

複合格式字串和物件清單會當做支援複合格式功能之方法的引數來使用。A composite format string and object list are used as arguments of methods that support the composite formatting feature. 複合格式字串是由零個或更多段與一個或多個格式項目混合的固定文字所組成,A composite format string consists of zero or more runs of fixed text intermixed with one or more format items. 固定文字是您選擇的任何文字,而每個格式項目都會對應到清單內的一個物件或 boxed 結構。The fixed text is any string that you choose, and each format item corresponds to an object or boxed structure in the list. 複合格式功能將會傳回新的結果字串,其中每一個格式項目都會由清單內對應物件的字串表示來取代。The composite formatting feature returns a new result string where each format item is replaced by the string representation of the corresponding object in the list.

請考量下列 Format 程式碼片段。Consider the following Format code fragment.

string name = "Fred";
String.Format("Name = {0}, hours = {1:hh}", name, DateTime.Now);
Dim name As String = "Fred"
String.Format("Name = {0}, hours = {1:hh}", name, DateTime.Now)

固定文字是 "Name =" 和 ", hours ="。The fixed text is "Name = " and ", hours = ". 格式項目為 "{0}" (其索引為 0,且對應至物件 name) 及 "{1:hh}" (其索引為 1,且對應至物件 DateTime.Now)。The format items are "{0}", whose index is 0, which corresponds to the object name, and "{1:hh}", whose index is 1, which corresponds to the object DateTime.Now.

格式項目語法Format Item Syntax

每個格式項目都會使用下列格式,並由下列元件所組成:Each format item takes the following form and consists of the following components:

{ index[,alignment][:formatString]}{ index[,alignment][:formatString]}

成對的大括號 ("{" 和 "}") 是必要的。The matching braces ("{" and "}") are required.

索引元件Index Component

強制的 index 元件 (也稱為參數規範) 是用以識別物件清單中對應項目的數字 (從 0 開始)。The mandatory index component, also called a parameter specifier, is a number starting from 0 that identifies a corresponding item in the list of objects. 也就是說,參數規範為 0 的格式項目會格式化清單中的第一個物件,而參數規範為 1 的格式項目會格式化清單中的第二個物件,依此類推。That is, the format item whose parameter specifier is 0 formats the first object in the list, the format item whose parameter specifier is 1 formats the second object in the list, and so on. 下列範例包含四個參數規範 (編號為 0 到 3),以表示小於 10 的質數:The following example includes four parameter specifiers, numbered zero through three, to represent prime numbers less than ten:

string primes;
primes = String.Format("Prime numbers less than 10: {0}, {1}, {2}, {3}",
                       2, 3, 5, 7 );
Console.WriteLine(primes);
// The example displays the following output:
//      Prime numbers less than 10: 2, 3, 5, 7
Dim primes As String
primes = String.Format("Prime numbers less than 10: {0}, {1}, {2}, {3}",
                       2, 3, 5, 7 )
Console.WriteLine(primes)
' The example displays the following output:
'      Prime numbers less than 10: 2, 3, 5, 7

多個格式項目可以藉由指定相同參數規範來參考物件清單中的相同項目。Multiple format items can refer to the same element in the list of objects by specifying the same parameter specifier. 例如,您可以格式化十六進位、科學記號和數字格式的相同數值,方法是指定複合格式字串 (例如:"0x{0:X} {0:E} {0:N}"),如下列範例所示。For example, you can format the same numeric value in hexadecimal, scientific, and number format by specifying a composite format string such as : "0x{0:X} {0:E} {0:N}", as the following example shows.

string multiple = String.Format("0x{0:X} {0:E} {0:N}",
                                Int64.MaxValue);
Console.WriteLine(multiple);
// The example displays the following output:
//      0x7FFFFFFFFFFFFFFF 9.223372E+018 9,223,372,036,854,775,807.00
Dim multiple As String = String.Format("0x{0:X} {0:E} {0:N}",
                                       Int64.MaxValue)
Console.WriteLine(multiple)
' The example displays the following output:
'      0x7FFFFFFFFFFFFFFF 9.223372E+018 9,223,372,036,854,775,807.00

每個格式項目皆可參考清單內的任何物件。Each format item can refer to any object in the list. 例如,如果有三個物件,您可以指定複合格式字串 (如:"{1} {0} {2}") 來格式化第二個、第一個和第三個物件。For example, if there are three objects, you can format the second, first, and third object by specifying a composite format string like this: "{1} {0} {2}". 不是格式項目所參考的物件會被忽略。An object that is not referenced by a format item is ignored. 如果參數規範指定超出物件清單範圍的項目,則會在執行階段擲回 FormatExceptionA FormatException is thrown at runtime if a parameter specifier designates an item outside the bounds of the list of objects.

對齊元件Alignment Component

選擇性 alignment 元件為帶正負號的整數,表示慣用的格式化欄位寬度。The optional alignment component is a signed integer indicating the preferred formatted field width. 如果 alignment 的值小於格式化字串的長度,則會忽略 alignment 並使用格式化字串的長度當做欄位寬度。If the value of alignment is less than the length of the formatted string, alignment is ignored and the length of the formatted string is used as the field width. 如果 alignment 為正數,欄位中的格式化資料會靠右對齊;如果 alignment 為負數,則會靠左對齊。The formatted data in the field is right-aligned if alignment is positive and left-aligned if alignment is negative. 如果填補有必要,則會使用泛空白字元 (White Space)。If padding is necessary, white space is used. 如果指定了 alignment,則需要逗號。The comma is required if alignment is specified.

下列範例會定義兩個陣列,一個包含員工的名稱,另一個包含他們在兩週內的工作時數。The following example defines two arrays, one containing the names of employees and the other containing the hours they worked over a two-week period. 複合格式字串會在 20 個字元的欄位中,將名稱靠左對齊,並且在 5 個字元的欄位中,將其工作時數靠右對齊。The composite format string left-aligns the names in a 20-character field, and right-aligns their hours in a 5-character field. 請注意,"N1" 標準格式字串也會用來格式化具有一個小數位數的時數。Note that the "N1" standard format string is also used to format the hours with one fractional digit.

using System;

public class Example
{
   public static void Main()
   {
      string[] names = { "Adam", "Bridgette", "Carla", "Daniel",
                         "Ebenezer", "Francine", "George" };
      decimal[] hours = { 40, 6.667m, 40.39m, 82, 40.333m, 80,
                                 16.75m };

      Console.WriteLine("{0,-20} {1,5}\n", "Name", "Hours");
      for (int ctr = 0; ctr < names.Length; ctr++)
         Console.WriteLine("{0,-20} {1,5:N1}", names[ctr], hours[ctr]);

   }
}
// The example displays the following output:
//       Name                 Hours
//
//       Adam                  40.0
//       Bridgette              6.7
//       Carla                 40.4
//       Daniel                82.0
//       Ebenezer              40.3
//       Francine              80.0
//       George                16.8
Module Example
   Public Sub Main()
      Dim names() As String = { "Adam", "Bridgette", "Carla", "Daniel",
                                "Ebenezer", "Francine", "George" }
      Dim hours() As Decimal = { 40, 6.667d, 40.39d, 82, 40.333d, 80,
                                 16.75d }

      Console.WriteLine("{0,-20} {1,5}", "Name", "Hours")
      Console.WriteLine()
      For ctr As Integer = 0 To names.Length - 1
         Console.WriteLine("{0,-20} {1,5:N1}", names(ctr), hours(ctr))
      Next
   End Sub
End Module
' The example displays the following output:
'       Name                 Hours
'
'       Adam                  40.0
'       Bridgette              6.7
'       Carla                 40.4
'       Daniel                82.0
'       Ebenezer              40.3
'       Francine              80.0
'       George                16.8

格式字串元件Format String Component

選擇性 formatString 元件是一個格式字串,適用於將格式化的物件類型。The optional formatString component is a format string that is appropriate for the type of object being formatted. 如果對應的物件為數值,指定標準或自訂的數值格式字串;如果對應的物件為 DateTime 物件,指定標準或自訂的日期和時間格式字串;或者,如果對應的物件為列舉值,指定列舉格式字串Specify a standard or custom numeric format string if the corresponding object is a numeric value, a standard or custom date and time format string if the corresponding object is a DateTime object, or an enumeration format string if the corresponding object is an enumeration value. 如果未指定 formatString,則會使用數值、日期和時間或列舉類型的一般 ("G") 格式規範。If formatString is not specified, the general ("G") format specifier for a numeric, date and time, or enumeration type is used. 如果指定 formatString,則需要冒號。The colon is required if formatString is specified.

下表列出 .NET Framework 類別庫中支援預先定義之格式字串的類型或類型分類,並提供列出支援之格式字串的主題連結。The following table lists types or categories of types in the .NET Framework class library that support a predefined set of format strings, and provides links to the topics that list the supported format strings. 請注意,字串格式是一種可延伸機制,可讓為所有現有類型定義新的格式字串,以及定義一組應用程式定義類型所支援的格式字串。Note that string formatting is an extensible mechanism that makes it possible to define new format strings for all existing types as well as to define a set of format strings supported by an application-defined type. 如需詳細資訊,請參閱 IFormattableICustomFormatter 介面主題。For more information, see the IFormattable and ICustomFormatter interface topics.

類型或類型分類Type or type category 請參閱See
日期和時間類型 (DateTimeDateTimeOffset)Date and time types (DateTime, DateTimeOffset) 標準日期和時間格式字串Standard Date and Time Format Strings

自訂日期和時間格式字串Custom Date and Time Format Strings
列舉類型 (衍生自 System.Enum 的所有類型)Enumeration types (all types derived from System.Enum) Enumeration Format StringsEnumeration Format Strings
數字類型 (BigIntegerByteDecimalDoubleInt16Int32Int64SByteSingleUInt16UInt32UInt64)Numeric types (BigInteger, Byte, Decimal, Double, Int16, Int32, Int64, SByte, Single, UInt16, UInt32, UInt64) Standard Numeric Format StringsStandard Numeric Format Strings

Custom Numeric Format StringsCustom Numeric Format Strings
Guid Guid.ToString(String)
TimeSpan 標準 TimeSpan 格式字串Standard TimeSpan Format Strings

自訂 TimeSpan 格式字串Custom TimeSpan Format Strings

逸出大括號Escaping Braces

左右大括號會被解譯成格式項目的開頭與結尾。Opening and closing braces are interpreted as starting and ending a format item. 因此,您必須使用逸出序列 (Escape Sequence),才能顯示字面上的左右大括號。Consequently, you must use an escape sequence to display a literal opening brace or closing brace. 請在固定文字中指定兩個左邊的大括號 ("{{"),以顯示一個左邊的大括號 ("{"),或者指定兩個右邊的大括號 ("}}") 來顯示一個右邊的大括號 ("}")。Specify two opening braces ("{{") in the fixed text to display one opening brace ("{"), or two closing braces ("}}") to display one closing brace ("}"). 格式項目中的括號會以它們出現的順序依序解譯,Braces in a format item are interpreted sequentially in the order they are encountered. 但是不支援解譯巢狀大括號。Interpreting nested braces is not supported.

解譯逸出括號的方式,可能會造成無法預期的結果。The way escaped braces are interpreted can lead to unexpected results. 例如,格式項目 "{{{0:D}}}" 原本是要顯示一個左邊大括號、一個格式化為十進位的數值和一個右邊大括號。For example, consider the format item "{{{0:D}}}", which is intended to display an opening brace, a numeric value formatted as a decimal number, and a closing brace. 然而,格式項目實際會以下列方式來解譯:However, the format item is actually interpreted in the following manner:

  1. 前面兩個左邊大括號 ("{{") 逸出,產生一個左邊大括號。The first two opening braces ("{{") are escaped and yield one opening brace.

  2. 接下來的三個字元 ("{0:") 會解譯成格式項目的開頭。The next three characters ("{0:") are interpreted as the start of a format item.

  3. 再下一個字元 ("D") 可能解譯成十進位 (Decimal) 標準數值格式規範,但後面兩個逸出的右邊大括號 ("}}") 會產生一個大括號。The next character ("D") would be interpreted as the Decimal standard numeric format specifier, but the next two escaped braces ("}}") yield a single brace. 由於結果字串 ("D}") 並非標準的數值格式規範,因此,結果字串會被解譯成自訂格式字串,表示會顯示成常值字串 "D}"。Because the resulting string ("D}") is not a standard numeric format specifier, the resulting string is interpreted as a custom format string that means display the literal string "D}".

  4. 最後的大括號 ("}") 會被解譯成格式項目的結尾。The last brace ("}") is interpreted as the end of the format item.

  5. 最後顯示的結果會是常值字串 "{D}",The final result that is displayed is the literal string, "{D}". 而要進行格式化的數值則不會顯示出來。The numeric value that was to be formatted is not displayed.

撰寫程式碼時,能夠避免錯誤解譯逸出大括號和格式項目的方法,就是個別地格式化大括號和格式項目。One way to write your code to avoid misinterpreting escaped braces and format items is to format the braces and format item separately. 也就是說,在第一個格式化作業中顯示常值的左邊大括號,在下一個作業中顯示格式項目的結果,接著在最終作業中顯示常值的右邊大括號。That is, in the first format operation display a literal opening brace, in the next operation display the result of the format item, then in the final operation display a literal closing brace. 下列範例將示範這個方法。The following example illustrates this approach.

int value = 6324;
string output = string.Format("{0}{1:D}{2}", 
                             "{", value, "}");
Console.WriteLine(output);
// The example displays the following output:
//       {6324}                            
Dim value As Integer = 6324
Dim output As String = String.Format("{0}{1:D}{2}", _
                                     "{", value, "}")
Console.WriteLine(output)   
' The example displays the following output:
'       {6324}

處理順序Processing Order

如果對複合格式方法的呼叫包含的 IFormatProvider 引數其值不是 null,則執行階段會呼叫其 IFormatProvider.GetFormat 方法要求 ICustomFormatter 實作。If the call to the composite formatting method includes an IFormatProvider argument whose value is not null, the runtime calls its IFormatProvider.GetFormat method to request an ICustomFormatter implementation. 如果該方法能夠傳回 ICustomFormatter 實作,它會快取長達複合格式方法的呼叫持續時間。If the method is able to return an ICustomFormatter implementation, it's cached for the duration of the call of the composite formatting method.

參數清單中每個對應於格式項目的值都會轉換為字串,如下所示:Each value in the parameter list that corresponds to a format item is converted to a string as follows:

  1. 如果要格式化的值是 null,則會傳回空字串 String.EmptyIf the value to be formatted is null, an empty string String.Empty is returned.

  2. 如果可以使用 ICustomFormatter 實作,則執行階段會呼叫其 Format 方法。If an ICustomFormatter implementation is available, the runtime calls its Format method. 它會將格式項目的 formatString 值 (如果有的話) 傳遞給方法;如果沒有,則會將 null 連同 IFormatProvider 實作一起傳遞。It passes the method the format item's formatString value, if one is present, or null if it's not, along with the IFormatProvider implementation. 如果 ICustomFormatter.Format 方法呼叫傳回 null,則會繼續執行到下一個步驟;否則,會傳回 ICustomFormatter.Format 呼叫的結果。If the call to the ICustomFormatter.Format method returns null, execution proceeds to the next step; otherwise, the result of the ICustomFormatter.Format call is returned.

  3. 如果值實作 IFormattable 介面,則會呼叫介面的 ToString(String, IFormatProvider) 方法。If the value implements the IFormattable interface, the interface's ToString(String, IFormatProvider) method is called. 如果格式項目中有 formatString 值的話,就會將該值傳遞給方法;如果沒有的話,則會傳遞 nullThe method is passed the formatString value, if one is present in the format item, or null if it's not. IFormatProvider 引數的判斷如下:The IFormatProvider argument is determined as follows:

  4. 呼叫類型的無參數 ToString 方法,該方法會覆寫 Object.ToString() 或繼承其基底類別的行為。The type's parameterless ToString method, which either overrides Object.ToString() or inherits the behavior of its base class, is called. 在這種情況下,會忽略 formatString 元件在格式項目中指定的格式字串 (如果有的話)。In this case, the format string specified by the formatString component in the format item, if it's present, is ignored.

對齊會在已經執行前面的步驟之後套用。Alignment is applied after the preceding steps have been performed.

程式碼範例Code Examples

下列範例顯示一個使用複合格式建立的字串,以及另一個使用物件的 ToString 方法建立的字串。The following example shows one string created using composite formatting and another created using an object's ToString method. 這兩個類型的格式化產生相等結果。Both types of formatting produce equivalent results.

string FormatString1 = String.Format("{0:dddd MMMM}", DateTime.Now);
string FormatString2 = DateTime.Now.ToString("dddd MMMM");
Dim FormatString1 As String = String.Format("{0:dddd MMMM}", DateTime.Now)
Dim FormatString2 As String = DateTime.Now.ToString("dddd MMMM") 

假設目前日期是五月的星期四,前面範例中兩個字串的值在美國英文文化特性中都是 Thursday MayAssuming that the current day is a Thursday in May, the value of both strings in the preceding example is Thursday May in the U.S. English culture.

Console.WriteLine 會公開與 String.Format 相同的功能。Console.WriteLine exposes the same functionality as String.Format. 這兩種方法唯一的差別在於,String.Format 會以字串形式傳回結果,而 Console.WriteLine 則會將結果寫入至與 Console 物件關聯的輸出資料流。The only difference between the two methods is that String.Format returns its result as a string, while Console.WriteLine writes the result to the output stream associated with the Console object. 下列範例使用 Console.WriteLine 方法,將 MyInt 的值格式化為貨幣值。The following example uses the Console.WriteLine method to format the value of MyInt to a currency value.

int MyInt = 100;
Console.WriteLine("{0:C}", MyInt);
// The example displays the following output 
// if en-US is the current culture:
//        $100.00
Dim MyInt As Integer = 100
Console.WriteLine("{0:C}", MyInt)
' The example displays the following output
' if en-US is the current culture:
'        $100.00

下列範例示範多個物件的格式化,其中包括使用兩種不同方式來格式化一個物件。The following example demonstrates formatting multiple objects, including formatting one object two different ways.

string myName = "Fred";
Console.WriteLine(String.Format("Name = {0}, hours = {1:hh}, minutes = {1:mm}",
      myName, DateTime.Now));
// Depending on the current time, the example displays output like the following:
//    Name = Fred, hours = 11, minutes = 30                 
Dim myName As String = "Fred"
Console.WriteLine(String.Format("Name = {0}, hours = {1:hh}, minutes = {1:mm}", _
                  myName, DateTime.Now))
' Depending on the current time, the example displays output like the following:
'    Name = Fred, hours = 11, minutes = 30                 

下列範例示範格式設定中的對齊用法。The following example demonstrates the use of alignment in formatting. 格式化的引數會放在兩個垂直線 (|) 字元之間以強調所產生的對齊。The arguments that are formatted are placed between vertical bar characters (|) to highlight the resulting alignment.

string myFName = "Fred";
string myLName = "Opals";
int myInt = 100;
string FormatFName = String.Format("First Name = |{0,10}|", myFName);
string FormatLName = String.Format("Last Name = |{0,10}|", myLName);
string FormatPrice = String.Format("Price = |{0,10:C}|", myInt); 
Console.WriteLine(FormatFName);
Console.WriteLine(FormatLName);
Console.WriteLine(FormatPrice);
Console.WriteLine();

FormatFName = String.Format("First Name = |{0,-10}|", myFName);
FormatLName = String.Format("Last Name = |{0,-10}|", myLName);
FormatPrice = String.Format("Price = |{0,-10:C}|", myInt);
Console.WriteLine(FormatFName);
Console.WriteLine(FormatLName);
Console.WriteLine(FormatPrice);
// The example displays the following output on a system whose current
// culture is en-US:
//          First Name = |      Fred|
//          Last Name = |     Opals|
//          Price = |   $100.00|
//
//          First Name = |Fred      |
//          Last Name = |Opals     |
//          Price = |$100.00   |
   Dim myFName As String = "Fred"
   Dim myLName As String = "Opals"

   Dim myInt As Integer = 100
   Dim FormatFName As String = String.Format("First Name = |{0,10}|", myFName)
   Dim FormatLName As String = String.Format("Last Name = |{0,10}|", myLName)
   Dim FormatPrice As String = String.Format("Price = |{0,10:C}|", myInt)
   Console.WriteLine(FormatFName)
   Console.WriteLine(FormatLName)
   Console.WriteLine(FormatPrice)
   Console.WriteLine()
   
   FormatFName = String.Format("First Name = |{0,-10}|", myFName)
   FormatLName = String.Format("Last Name = |{0,-10}|", myLName)
   FormatPrice = String.Format("Price = |{0,-10:C}|", myInt)
   Console.WriteLine(FormatFName)
   Console.WriteLine(FormatLName)
   Console.WriteLine(FormatPrice)
   ' The example displays the following output on a system whose current
   ' culture is en-US:
   '          First Name = |      Fred|
   '          Last Name = |     Opals|
   '          Price = |   $100.00|
   '
   '          First Name = |Fred      |
   '          Last Name = |Opals     |
   '          Price = |$100.00   |

另請參閱See also