若要檢視英文版的文章,請選取 [原文] 核取方塊。您也可以將滑鼠指標移到文字上,即可在快顯視窗顯示英文原文。
譯文
原文

.NET Framework 中的格式化類型

 

格式化是將類別、結構或列舉值的執行個體轉換成字串表示的過程,通常是為了將結果字串展示予使用者,或是為了將字串藉還原序列化方式還原成原始的資料類型。 這種轉換可能面臨幾項挑戰:

  • 值的內部儲存方式不見得反映出使用者想要的檢視方式。 例如,電話號碼可能以 8009999999 的格式儲存,但這並不太符合使用者的閱讀習慣。 應該改以顯示成 800-999-9999。 如需以此方式格式化數字的範例,請參閱自訂格式字串一節。

  • 物件轉換後的字串表示有時候並不符合直覺。 例如,Temperature 物件或 Person 物件的字串表示應該為何種格式,就不是那麼清楚。 如需以各種方式將 Temperature 物件格式化的範例,請參閱標準格式字串一節。

  • 值的格式通常需要符合文化特性。 例如,如果應用程式需要使用數字來表達貨幣值,則數值字串應該包含目前文化特性的貨幣符號、群組分隔符號 (即大部分文化特性中的千位分隔符號) 和小數點符號。 如需範例,請參閱以格式提供者和 IFormatProvider 介面進行符合文化特性的格式化一節。

  • 應用程式可能需要以不同的方式來顯示相同的值。 例如,應用程式在表示列舉成員時,在做法上可能是顯示其名稱的字串表示,或顯示其基礎值。 如需以不同方式格式化 DayOfWeek 列舉成員的範例,請參閱標準格式字串一節。

System_CAPS_note注意

格式化會將某種類型的值轉換為字串表示。 剖析是格式化的反向操作。 剖析作業會從資料類型的字串表示來建立資料類型的執行個體。 如需將字串轉換為其他資料類型的相關資訊,請參閱在 .NET Framework 中剖析字串

.NET Framework 提供豐富的格式化支援,可滿足開發人員的這些需求。

本概觀包含下列各節:

格式化機制的基礎在於 Object.ToString 方法的預設實作,這將於本主題稍後的使用 ToString 方法的預設格式一節中討論。 不過,.NET Framework 提供幾種方式來修改和擴充其預設格式化支援。 這些需求包括下列各項:

  • 覆寫 Object.ToString 方法來自訂物件值的字串表示。 如需詳細資訊,請參閱本主題稍後的覆寫 ToString 方法一節。

  • 定義格式規範,格式規範讓物件值的字串表示可以採用多種形式。 例如,下列陳述式中的 "X" 格式規範會將整數轉換為十六進位值的字串表示。

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

    如需格式規範的詳細資訊,請參閱 ToString 方法和格式字串一節。

  • 透過格式提供者來採用特定文化特性的格式化慣例。 例如,下列陳述式會使用 en-US 文化特性的格式化慣例來顯示貨幣值。

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

    如需以格式提供者進行格式化的詳細資訊,請參閱格式提供者和 IFormatProvider 介面一節。

  • 實作 IFormattable 介面,以同時支援使用 Convert 類別和複合格式來轉換字串。 如需詳細資訊,請參閱 IFormattable 介面一節。

  • 使用複合格式將值的字串表示嵌入更大的字串中。 如需詳細資訊,請參閱複合格式一節。

  • 實作 ICustomFormatterIFormatProvider 來提供完整的自訂格式解決方案。 如需詳細資訊,請參閱使用 ICustomFormatter 的自訂格式一節。

下列各節會討論這些將物件轉換為其字串表示的方法。

回到頁首

每個衍生自 System.Object 的類型都會自動繼承無參數的 ToString 方法,這個方法預設會傳回類型的名稱。 下列範例示範預設的 ToString 方法。 範例中會定義一個不具任何實作的 Automobile 類別。 當具現化這個類別並呼叫其 ToString 方法時,會顯示這個類別的類型名稱。 請注意,在範例中不會明確呼叫 ToString 方法。 Console.WriteLine(Object) 方法會隱含呼叫本身所收到做為引數傳遞之物件的 ToString 方法。

using System;

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

public class Example
{
   public static void Main()
   {
      Automobile firstAuto = new Automobile();
      Console.WriteLine(firstAuto);
   }
}
// The example displays the following output:
//       Automobile
System_CAPS_warning警告

從 Windows 8.1 開始,Windows 執行階段 會包含具有單一方法 IStringable.ToStringIStringable 介面,該介面會提供預設的格式化支援。 不過,不建議 Managed 類型實作 IStringable 介面。 如需詳細資訊,請參閱 Windows 執行階段 參考頁面上的<IStringableObject.ToString 介面>一節。

因為除介面以外的所有其他類型都會衍生自 Object,所以您的自訂類別或結構會自動被賦予此功能。 不過,預設的 ToString 方法提供的功能有限:它雖然可以識別類型,但無法提供類型執行個體的任何資訊。 若要提供物件的字串表示來表達該物件的相關資訊,您必須覆寫 ToString 方法。

System_CAPS_note注意

結構會繼承自 ValueType,而後者又會衍生自 Object 雖然 ValueType 會覆寫 Object.ToString,但實作方法是相同的。

回到頁首

顯示類型的名稱通常用途不大,亦無法讓您類型的使用者藉以區分不同的執行個體。 不過,您可以覆寫 ToString 方法,以更實用的方式表示物件的值。 下列範例定義 Temperature 物件,並覆寫其 ToString 方法來顯示攝氏溫度。

using System;

public class Temperature
{
   private decimal temp;

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

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

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

在 .NET Framework 中,每個基本值類型的 ToString 方法都已經過覆寫來顯示物件的值,而非物件的名稱。 下表顯示各基本類型如何覆寫 ToString 方法。 請注意,大部分經過覆寫的方法都會呼叫 ToString 方法的另一個多載,並且將 "G" 格式規範 (此規範定義此類型的一般格式) 和 IFormatProvider 物件 (此物件表示目前文化特性) 傳遞至這個多載。

類型

ToString 覆寫

Boolean

傳回 Boolean.TrueStringBoolean.FalseString

Byte

呼叫 Byte.ToString("G", NumberFormatInfo.CurrentInfo),以根據目前的文化特性來格式化 Byte 值。

Char

以字串形式傳回字元。

DateTime

呼叫 DateTime.ToString("G", DatetimeFormatInfo.CurrentInfo),以根據對目前的文化特性來格式化日期和時間值。

Decimal

呼叫 Decimal.ToString("G", NumberFormatInfo.CurrentInfo),以根據目前的文化特性來格式化 Decimal 值。

Double

呼叫 Double.ToString("G", NumberFormatInfo.CurrentInfo),以根據目前的文化特性來格式化 Double 值。

Int16

呼叫 Int16.ToString("G", NumberFormatInfo.CurrentInfo),以根據目前的文化特性來格式化 Int16 值。

Int32

呼叫 Int32.ToString("G", NumberFormatInfo.CurrentInfo),以根據目前的文化特性來格式化 Int32 值。

Int64

呼叫 Int64.ToString("G", NumberFormatInfo.CurrentInfo),以根據目前的文化特性來格式化 Int64 值。

SByte

呼叫 SByte.ToString("G", NumberFormatInfo.CurrentInfo),以根據目前的文化特性來格式化 SByte 值。

Single

呼叫 Single.ToString("G", NumberFormatInfo.CurrentInfo),以根據目前的文化特性來格式化 Single 值。

UInt16

呼叫 UInt16.ToString("G", NumberFormatInfo.CurrentInfo),以根據目前的文化特性來格式化 UInt16 值。

UInt32

呼叫 UInt32.ToString("G", NumberFormatInfo.CurrentInfo),以根據目前的文化特性來格式化 UInt32 值。

UInt64

呼叫 UInt64.ToString("G", NumberFormatInfo.CurrentInfo),以根據目前的文化特性來格式化 UInt64 值。

回到頁首

當物件只有單一字串表示時,使用預設 ToString 方法或覆寫 ToString 都沒有問題。 不過,物件的值通常有多種表示。 例如,溫度可以用華氏、攝氏或開氏溫度表示。 同樣地,整數值 10 可以用許多方式表示,包括 10、10.0、1.0e01 或 $10.00。

為了讓單一值可以具有多種字串表示,.NET Framework 使用格式字串。 格式字串是包含一個或多個預先定義之格式規範的字串,這個字串是單一字元或一組字元,用於定義 ToString 方法應採用的輸出格式。 然後,格式字串會當做參數傳遞至物件的 ToString 方法,以決定如何呈現該物件的值的字串表示。

.NET Framework 中所有的數字類型、日期和時間類型,以及列舉類型,都支援一組預先定義的格式規範。 您也可以利用格式字串定義多種字串表示給您應用程式中定義的資料類型。

標準格式字串包含單一格式規範 (一個字母字元,定義套用此規範之物件的字串表示) 和選擇性的精確度規範 (這個規範影響結果字串中顯示的位數)。 如果省略或不支援精確度規範,則標準格式規範與標準格式字串無異。

.NET Framework 針對所有數值類型、所有日期和時間類型,以及所有列舉類型,都定義一組標準格式規範。 例如,這些分類每個都支援 "G" 標準格式規範 (這個規範定義該類型之值的一般字串表示)。

列舉類型的標準格式字串直接控制了值的字串表示。 傳遞給列舉值的 ToString 方法的格式字串決定了該值是以其字串名稱 ("G" 和 "F" 格式規範)、基礎整數值 ("D" 格式規範),還是十六進位值 ("X" 格式規範) 來顯示。 下列範例示範如何使用標準格式字串來格式化 DayOfWeek 列舉值。

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

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

如需列舉格式字串的相關資訊,請參閱列舉類型格式字串

數值類型的標準格式字串定義出的結果字串之確切外觀通常是由一個或多個屬性值所控制。 例如,"C" 格式規範會將數字格式化為貨幣值。 當您將 "C" 格式規範做為唯一參數來呼叫 ToString 方法時,會使用目前文化特性之 NumberFormatInfo 物件中的下列屬性值來定義數值的字串表示:

此外,數值格式字串也可以包含精確度規範。 這個規範的意義視搭配使用的格式字串而定,但通常是表示結果字串中應該顯示的總位數或小數位數。 例如,下列範例會使用 "X4" 標準數值字串和精確度規範,建立具有四個十六進位數字的字串值。

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

如需標準數值格式字串的詳細資訊,請參閱標準數值格式字串

日期和時間值的標準格式字串是特定 DateTimeFormatInfo 屬性所儲存之自訂格式字串的別名。 例如,以 "D" 格式規範來呼叫日期和時間值的 ToString 方法,將會使用目前文化特性之 DateTimeFormatInfo.LongDatePattern 屬性中所儲存的自訂格式字串來顯示日期和時間 (如需自訂格式字串的詳細資訊,請參閱下一節)。 下列範例示範這種關聯性。

using System;
using System.Globalization;

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

如需標準日期和時間格式字串的詳細資訊,請參閱標準日期和時間格式字串

對於應用程式定義的物件,您也可以使用標準格式字串來定義由該物件的 ToString(String) 方法所產生的字串表示。 您可以定義您的物件所支援的特定標準格式規範,並且決定這項規範是否區分大小寫。 您對 ToString(String) 方法的實作應該要能支援:

  • "G" 格式規範,表示物件的慣用或通用格式。 您物件的 ToString 方法的無參數多載應該要呼叫這個方法的 ToString(String) 多載,並且將 "G" 標準格式字串傳遞給這個方法。

  • 支援等於 null 參考 (在 Visual Basic 中為 Nothing) 的格式規範。 等於 null 參考的格式規範應該要視為相當於 "G" 格式規範。

例如,Temperature 類別可以在內部以攝氏儲存溫度,並透過格式規範以攝氏、華氏和開氏溫度來表示 Temperature 物件的值。 下列範例提供一個實例。

using System;

public class Temperature
{
   private decimal m_Temp;

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

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

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

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

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

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

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

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

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

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

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

回到頁首

除了標準格式字串,.NET Framework 也為數值及日期和時間值定義了自訂格式字串。 自訂格式字串由一個或多個自訂格式規範組成,這些規範定義了值的字串表示。 例如,自訂日期和時間格式字串 "yyyy/mm/dd hh:mm:ss.ffff t zzz" 會將日期轉換為其字串表示,以 en-US 文化特性而言為 "2008/11/15 07:45:00.0000 P -08:00" 形式。 同樣地,自訂格式字串 "0000" 會將整數值 12 轉換為 "0012"。 如需完整的自訂格式字串清單,請參閱自訂日期和時間格式字串自訂數值格式字串

如果格式字串由單一自訂格式規範組成,則應該在格式規範前面加上百分比 (%) 符號,以避免與標準格式規範產生混淆。 下列範例會使用 "M" 自訂格式規範來顯示特定日期的一位數或兩位數月份。

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

日期和時間值的許多標準格式字串都是自訂格式字串 (這些自訂格式字串由 DateTimeFormatInfo 物件的屬性所定義) 的別名。 自訂格式字串也提供極大的彈性,來提供應用程式定義的數值或日期和時間值格式。 您可以將多個自訂格式規範結合成單一自訂格式字串,以自訂您的數值及日期和時間值結果字串。 下列範例定義的自訂格式字串,會在月份名稱、日期和年後面顯示加上括號的星期。

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

下列範例會定義自訂格式字串,該字串會將 Int64 值顯示為標準的七位數美國電話號碼且包含其區碼。

using System;

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

雖然標準格式字串通常能夠為應用程式定義的類型解決大部分的格式需求,但您也可以定義自訂格式規範來格式化您的類型。

回到頁首

所有數字類型 (也就是 ByteDecimalDoubleInt16Int32Int64SByteSingleUInt16UInt32UInt64BigInteger 類型)

以及 DateTimeDateTimeOffsetTimeSpanGuid,和所有列舉類型,都支援以格式字串進行格式化。 如需每個類型所支援特定格式字串的詳細資訊,請參閱下列主題

標題

定義

標準數值格式字串

說明建立數值常用之字串表示的標準格式字串。

自訂數值格式字串

說明建立應用程式專屬數值格式的自訂格式字串。

標準日期和時間格式字串

說明建立 DateTime 值之常用字串表示的標準格式字串。

自訂日期和時間格式字串

說明建立應用程式專屬 DateTime 值格式的自訂格式字串。

標準 TimeSpan 格式字串

說明建立時間間隔之常用字串表示的標準格式字串。

自訂 TimeSpan 格式字串

說明建立應用程式專屬數值格式的自訂格式字串。

列舉類型格式字串

說明用來建立列舉值之字串表示的標準格式字串。

Guid.ToString(String)

描述 Guid 值的標準格式字串。

雖然格式規範可讓您自訂物件的格式,但如果要為物件產生有意義的字串表示,您通常還需要其他格式設定資訊。 例如,如果要使用 "C" 標準格式字串或自訂格式字串 (例如 "$ #,#.00") 將數字格式化為貨幣值,您至少還需要有正確的貨幣符號、群組分隔符號和小數分隔符號的相關資訊。 在 .NET Framework 中,這些額外的資訊是透過 IFormatProvider 介面取得,而這個介面會做為參數放在數字類型及日期和時間類型之 ToString 方法的一個或多個多載中。 IFormatProvider 實作會在 .NET Framework 中用來支援文化特性特有的格式。 下列範例將示範以代表不同文化特性的三個 IFormatProvider 物件進行格式化時,物件的字串表示會有什麼樣的變化。

using System;
using System.Globalization;

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

IFormatProvider 介面包含一個 GetFormat(Type) 方法,這個方法具有單一參數來指定可提供格式設定資訊之物件的類型。 如果這個方法可以提供該類型的物件,則會傳回該物件。 否則會傳回 null 參考 (在 Visual Basic 中為 Nothing)。

IFormatProvider.GetFormat 是一種回呼方法。 當您呼叫包含 ToString 參數的 IFormatProvider 方法多載時,這個多載會呼叫該 GetFormat 物件的 IFormatProvider 方法。 GetFormat 方法負責將提供必要格式設定資訊的物件 (由其 formatType 參數指定),傳回給 ToString 方法。

有幾個格式化或字串轉換方法都包含 IFormatProvider 類型的參數,但通常呼叫方法時,會忽略這個參數的值。 下表列出一些使用這個參數的格式化方法,以及這些方法傳遞至 Type 方法的 IFormatProvider.GetFormat 物件的類型。

方法

formatType 參數的類型

數字類型的 ToString 方法

System.Globalization.NumberFormatInfo

日期和時間類型的 ToString 方法

System.Globalization.DateTimeFormatInfo

String.Format

System.ICustomFormatter

StringBuilder.AppendFormat

System.ICustomFormatter

System_CAPS_note注意

數字類型及日期和時間類型的 ToString 方法都含有多載,而其中只有某些多載會包含 IFormatProvider 參數。 如果方法沒有 IFormatProvider 類型的參數,則會改以傳遞 CultureInfo.CurrentCulture 屬性所傳回的物件。 例如,呼叫預設的 Int32.ToString() 方法最終會產生如下的方法呼叫:Int32.ToString("G", System.Globalization.CultureInfo.CurrentCulture)

.NET Framework 提供三個實作 IFormatProvider 的類別:

您也可以實作自己的格式提供者來取代上述任何一個類別。 不過,您實作的 GetFormat 方法如果必須提供格式設定資訊給 ToString 方法,則必須傳回上表所列之類型的物件。

回到頁首

根據預設,數值格式會區分文化特性。 如果當您呼叫格式化方法時未指定文化特性,則會使用目前執行緒文化特性的格式設定慣例。 下列範例將說明這種情形,其中目前執行緒文化特性會變更四次,然後呼叫 Decimal.ToString(String) 方法。 在各案例中,結果字串都會反映目前文化特性的格式設定慣例。 這是因為 ToStringToString(String) 方法會包裝對每個數值類型之 ToString(String, IFormatProvider) 方法的呼叫。

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

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

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

您也可以呼叫具有 ToString 參數的 provider 多載並且將下列任一項傳遞給它,藉此格式化特定文化特性的數值:

下列範例將使用 NumberFormatInfo 物件,該物件表示用於格式化浮點數的英文 (美國) 和英文 (英國) 文化特性,以及法文和俄文中性文化特性。

using System;
using System.Globalization;

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

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

根據預設,日期和時間值的格式區分文化特性。 如果當您呼叫格式化方法時未指定文化特性,則會使用目前執行緒文化特性的格式設定慣例。 下列範例將說明這種情形,其中目前執行緒文化特性會變更四次,然後呼叫 DateTime.ToString(String) 方法。 在各案例中,結果字串都會反映目前文化特性的格式設定慣例。 這是因為 DateTime.ToString()DateTime.ToString(String)DateTimeOffset.ToString()DateTimeOffset.ToString(String) 方法會包裝 DateTime.ToString(String, IFormatProvider)DateTimeOffset.ToString(String, IFormatProvider) 方法的呼叫。

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

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

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

您也可以呼叫具有 DateTime.ToString 參數的 DateTimeOffset.ToStringprovider 多載並且將下列任一項傳遞給它,藉此格式化特定文化特性的日期和時間值:

下列範例將使用 DateTimeFormatInfo 物件,該物件表示用於格式化日期的英文 (美國) 和英文 (英國) 文化特性,以及法文和俄文中性文化特性。

using System;
using System.Globalization;

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

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

以格式字串和 ToString 參數來多載 IFormatProvider 方法的類型,通常也會實作 IFormattable 介面。 這個介面具有單一成員 IFormattable.ToString(String, IFormatProvider),這個成員同時包含格式字串和格式提供者做為參數。

針對您的應用程式定義的類別來實作 IFormattable 介面有兩項好處:

下列範例定義一個實作 Temperature 介面的 IFormattable 類別。 這個類別支援 "C" 或 "G" 格式規範來顯示攝氏溫度、支援 "F" 格式規範來顯示華氏溫度,也支援 "K" 格式規範來顯示絕對溫度。

using System;
using System.Globalization;

public class Temperature : IFormattable
{
   private decimal m_Temp;

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

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

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

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

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

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

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

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

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

下列範例會執行個體化 Temperature 物件。 然後呼叫 ToString 方法,並使用數個複合格式字串來取得 Temperature 物件的不同字串表示。 其中每個方法又呼叫 IFormattable 類別的 Temperature 實作。

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

回到頁首

某些方法 (例如 String.FormatStringBuilder.AppendFormat) 支援複合格式。 複合格式字串是一種範本,可傳回由零個、一個或更多物件的字串表示所組成的單一字串。 複合格式字串中的每個物件都以有索引的格式項目來表示。 格式項目的索引對應至其所表示的物件在方法的參數清單中的位置。 索引以零為起始。 例如,在下列對 String.Format 方法的呼叫中,第一個格式項目 {0:D}thatDate 的字串表示所取代、第二個格式項目 {1}item1 的字串表示所取代,而第三個格式項目 {2:C2}item1.Value 的字串表示所取代。

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

除了取代具有對應物件字串表示格式的項目,格式項目也可讓您控制下列幾項:

  • 當物件實作 IFormattable 介面,並支援格式字串時,物件表示為字串的特定方式。 您可將格式項目索引後面接上 : (冒號) ,後面再接有效的格式字串,以執行此作業。 前一個範例採用的方法是用 "d" (簡短日期模式) 格式字串來格式化日期值 (例如 {0:d}) 以及用 "C2" 格式字串 (例如 {2:C2}) 來格式化數值,以表示具有兩個小數位數的十進位數字之貨幣值。

  • 包含物件字串表示法及在該欄位中對齊方式的字串表示法之欄位寬度。 您可將格式項目索引後面接上 , (逗號) ,後面再接欄位寬度,以執行此作業。 如果欄位寬度是正值,則此欄位中的字串為靠右對齊;如果欄位寬度是負值,則為靠左對齊。 下列範例在長 20 個字元的欄位中將日期值靠左對齊,並在長 11 個字元的欄位中將具有一位小數位數的十進位值靠右對齊。

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

    請注意如果對齊字串元件和格式字串元件都存在,則前者優先於後者 (例如,{0,-20:g})。

如需複合格式的詳細資訊,請參閱複合格式

回到頁首

String.Format(IFormatProvider, String, Object[])StringBuilder.AppendFormat(IFormatProvider, String, Object[]) 這兩個複合格式方法包含支援自訂格式的格式提供者參數。 呼叫這兩種格式化方法的任一種時,會將表示 Type 介面的 ICustomFormatter 物件傳遞至格式提供者的 GetFormat 方法。 然後,GetFormat 方法負責傳回 ICustomFormatter 實作,這個實作提供自訂格式。

ICustomFormatter 介面具有單一方法 Format(String, Object, IFormatProvider),複合格式化方法會自動針對複合格式字串中的每個格式項目,各呼叫一次這個方法。 Format(String, Object, IFormatProvider) 方法具有三個參數:格式字串 (表示格式項目中的 formatString 引數)、要格式化的物件,以及提供格式化服務的 IFormatProvider 物件。 實作 ICustomFormatter 的物件通常也會實作 IFormatProvider,所以這最後一個參數是對自訂格式化類別的參考。 方法會傳回要格式化之物件的自訂格式化字串表示。 如果方法無法格式化物件,則應該傳回 null 參考 (在 Visual Basic 中為 Nothing)。

下列範例提供一個名為 ICustomFormatterByteByByteFormatter 實作,這個實作會將整數值顯示為一連串由兩位數十六進位值再加上一個空格所組成的數列。

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

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

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

      byte[] bytes;
      string output = null;

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

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

      return output.Trim();
   }
}

下列範例會使用 ByteByByteFormatter 類別來格式化整數值。 請注意,ICustomFormatter.Format 方法在第二個 String.Format(IFormatProvider, String, Object[]) 方法呼叫中被呼叫不只一次,且第三個方法呼叫中使用預設 NumberFormatInfo 提供者,因為 ByteByByteFormatter.Format 方法無法辨認 "N0" 格式字串而傳回 null 參考 (在 Visual Basic 中為 Nothing)。

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

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

回到頁首

標題

定義

標準數值格式字串

說明建立數值常用之字串表示的標準格式字串。

自訂數值格式字串

說明建立應用程式專屬數值格式的自訂格式字串。

標準日期和時間格式字串

說明建立 DateTime 值之常用字串表示的標準格式字串。

自訂日期和時間格式字串

說明建立應用程式專屬 DateTime 值格式的自訂格式字串。

標準 TimeSpan 格式字串

說明建立時間間隔之常用字串表示的標準格式字串。

自訂 TimeSpan 格式字串

說明建立應用程式專屬數值格式的自訂格式字串。

列舉類型格式字串

說明用來建立列舉值之字串表示的標準格式字串。

複合格式

描述如何將一個或更多的格式化值嵌入字串。 字串可以隨後顯示在主控台 (Console) 或寫入資料流。

執行格式化作業

列出各主題,提供執行特定格式設定作業的逐步指示。

在 .NET Framework 中剖析字串

說明如何將物件初始化為這些物件的字串表示所描述的值。 剖析是格式化的反向作業。

回到頁首

顯示: