NumberFormatInfo 類別

本文提供此 API 參考文件的補充備註。

類別 NumberFormatInfo 包含格式化和剖析數值時所使用的特定文化特性資訊。 此資訊包括貨幣符號、十進位符號、群組分隔符,以及正負號的符號。

具現化 NumberFormatInfo 物件

您可以具現化 NumberFormatInfo 物件,此物件代表目前文化特性、不因文化特性、特定文化特性或中性文化特性的格式化慣例。

具現化目前文化特性的 NumberFormatInfo 物件

您可以透過下列任何方式具現化 NumberFormatInfo 目前文化特性的物件。 在每個案例中,傳 NumberFormatInfo 回的物件都是唯讀的。

下列範例會使用這三種方式來建立 NumberFormatInfo 代表目前文化特性之格式設定慣例的物件。 它也會擷取 屬性的值 IsReadOnly ,以說明每個物件都是唯讀的。

using System;
using System.Globalization;

public class InstantiateEx1
{
    public static void Main()
    {
        NumberFormatInfo current1 = CultureInfo.CurrentCulture.NumberFormat;
        Console.WriteLine(current1.IsReadOnly);

        NumberFormatInfo current2 = NumberFormatInfo.CurrentInfo;
        Console.WriteLine(current2.IsReadOnly);

        NumberFormatInfo current3 = NumberFormatInfo.GetInstance(CultureInfo.CurrentCulture);
        Console.WriteLine(current3.IsReadOnly);
    }
}
// The example displays the following output:
//       True
//       True
//       True

您可以建立可 NumberFormatInfo 寫入的物件,以下列任何方式代表目前文化特性的慣例:

下列範例說明這兩種具現化 NumberFormatInfo 物件的方式,並顯示其 IsReadOnly 屬性的值,以說明物件不是只讀的。

using System;
using System.Globalization;

public class InstantiateEx2
{
    public static void Main()
    {
        NumberFormatInfo current1 = NumberFormatInfo.CurrentInfo;
        current1 = (NumberFormatInfo)current1.Clone();
        Console.WriteLine(current1.IsReadOnly);

        CultureInfo culture2 = CultureInfo.CreateSpecificCulture(CultureInfo.CurrentCulture.Name);
        NumberFormatInfo current2 = culture2.NumberFormat;
        Console.WriteLine(current2.IsReadOnly);
    }
}
// The example displays the following output:
//       False
//       False

請注意,Windows 操作系統可讓使用者透過 控制台 中的 Region 和 Language 專案覆寫數值格式設定和剖析作業中使用的部分NumberFormatInfo屬性值。 例如,文化特性為英文(美國)的使用者可能會選擇將貨幣值顯示為 1.1 美元,而不是預設值 $1.1。 以 NumberFormatInfo 先前所討論方式擷取的物件都會反映這些使用者覆寫。 如果這是不想要的,您可以藉由呼叫 CultureInfo.CultureInfo(String, Boolean) 建構函式並提供 自變數的 值false,來建立NumberFormatInfo不會反映使用者覆寫的物件(而且也是可擦寫的,而不是只讀的useUserOverride)。 下列範例提供目前文化特性為英文(美國)且貨幣符號已從預設值 $ 變更為 USD 的系統圖例。

using System;
using System.Globalization;

public class InstantiateEx3
{
    public static void Main()
    {
        CultureInfo culture;
        NumberFormatInfo nfi;

        culture = CultureInfo.CurrentCulture;
        nfi = culture.NumberFormat;
        Console.WriteLine("Culture Name:    {0}", culture.Name);
        Console.WriteLine("User Overrides:  {0}", culture.UseUserOverride);
        Console.WriteLine("Currency Symbol: {0}\n", culture.NumberFormat.CurrencySymbol);

        culture = new CultureInfo(CultureInfo.CurrentCulture.Name, false);
        Console.WriteLine("Culture Name:    {0}", culture.Name);
        Console.WriteLine("User Overrides:  {0}", culture.UseUserOverride);
        Console.WriteLine("Currency Symbol: {0}", culture.NumberFormat.CurrencySymbol);
    }
}
// The example displays the following output:
//       Culture Name:    en-US
//       User Overrides:  True
//       Currency Symbol: USD
//
//       Culture Name:    en-US
//       User Overrides:  False
//       Currency Symbol: $

CultureInfo.UseUserOverride如果屬性設定為 true,則屬性CultureInfo.DateTimeFormatCultureInfo.NumberFormatCultureInfo.TextInfo 也會從用戶設定中擷取。 如果使用者設定與對象相關聯的 CultureInfo 文化特性不相容(例如,如果選取的行事曆不是 屬性列出的 OptionalCalendars 其中一個行事曆),則方法和屬性值未定義。

具現化不因文化特性而異的 NumberFormatInfo 物件

不因文化特性而異的文化特性代表不區分文化特性的文化特性。 它是以英文為基礎,但不是以任何特定的英文國家/地區為基礎。 雖然特定文化特性的數據可以是動態的,而且可以變更以反映新的文化慣例或使用者喜好設定,但非變異文化特性的數據不會變更。 NumberFormatInfo物件,表示不因文化特性而異的格式化慣例,可用於格式化結果字串不應因文化特性而異的作業。

您可以具現化 NumberFormatInfo 物件,此物件代表不因文化特性而異的格式慣例,其方式如下:

下列範例會使用上述每一 NumberFormatInfo 種方法來具現化代表不因文化特性而異的物件。 然後,它會指出物件是否為唯讀,

using System;
using System.Globalization;

public class InstantiateEx4
{
    public static void Main()
    {
        NumberFormatInfo nfi;

        nfi = System.Globalization.NumberFormatInfo.InvariantInfo;
        Console.WriteLine(nfi.IsReadOnly);

        nfi = CultureInfo.InvariantCulture.NumberFormat;
        Console.WriteLine(nfi.IsReadOnly);

        nfi = new NumberFormatInfo();
        Console.WriteLine(nfi.IsReadOnly);
    }
}
// The example displays the following output:
//       True
//       True
//       False

具現化特定文化特性的 NumberFormatInfo 物件

特定文化特性代表在特定國家/地區中說的語言。 例如,en-US 是代表 美國 中說英語的特定文化特性,en-CA 是代表加拿大口語的特定文化特性。 您可以具現化 NumberFormatInfo 物件,以下列方式呈現特定文化特性的格式設定慣例:

下列範例會使用這四種方式來建立 NumberFormatInfo 物件,以反映印尼(印尼)文化特性的格式設定慣例。 它也會指出每個物件是否為唯讀。

using System;
using System.Globalization;

public class InstantiateEx5
{
    public static void Main()
    {
        CultureInfo culture;
        NumberFormatInfo nfi;

        nfi = CultureInfo.GetCultureInfo("id-ID").NumberFormat;
        Console.WriteLine("Read-only: {0}", nfi.IsReadOnly);

        culture = new CultureInfo("id-ID");
        nfi = NumberFormatInfo.GetInstance(culture);
        Console.WriteLine("Read-only: {0}", nfi.IsReadOnly);

        culture = CultureInfo.CreateSpecificCulture("id-ID");
        nfi = culture.NumberFormat;
        Console.WriteLine("Read-only: {0}", nfi.IsReadOnly);

        culture = new CultureInfo("id-ID");
        nfi = culture.NumberFormat;
        Console.WriteLine("Read-only: {0}", nfi.IsReadOnly);
    }
}
// The example displays the following output:
//       Read-only: True
//       Read-only: False
//       Read-only: False
//       Read-only: False

具現化中性文化特性的 NumberFormatInfo 物件

中性文化特性代表與國家/地區無關的文化特性或語言。 它通常是一或多個特定文化特性的父系。 例如,fr 是法文語言的中性文化特性,也是fr-FR文化特性的父系。 您可以建立 NumberFormatInfo 物件,該物件代表中性文化特性的格式設定慣例,方式與建立 NumberFormatInfo 代表特定文化特性之格式化慣例的物件相同。

不過,因為它獨立於特定國家/地區,中性文化缺乏特定文化特性的格式資訊。 .NET 不以泛型值填 NumberFormatInfo 入物件,而是傳 NumberFormatInfo 回物件,該物件會反映屬於中性文化特性子系之特定文化特性的格式慣例。 例如, NumberFormatInfo 中性 en 文化特性的物件會反映 en-US 文化特性的格式設定慣例, NumberFormatInfo 而 fr 文化特性的物件則反映 fr-FR 文化特性的格式設定慣例。

您可以使用如下的程式代碼來判斷每個中性文化特性所代表的特定文化特性格式慣例。

using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.Reflection;

public class InstantiateEx6
{
    public static void Main()
    {
        // Get all the neutral cultures
        List<String> names = new List<String>();
        Array.ForEach(CultureInfo.GetCultures(CultureTypes.NeutralCultures),
                      culture => names.Add(culture.Name));
        names.Sort();
        foreach (var name in names)
        {
            // Ignore the invariant culture.
            if (name == "") continue;

            ListSimilarChildCultures(name);
        }
    }

    private static void ListSimilarChildCultures(string name)
    {
        // Create the neutral NumberFormatInfo object.
        NumberFormatInfo nfi = CultureInfo.GetCultureInfo(name).NumberFormat;
        // Retrieve all specific cultures of the neutral culture.
        CultureInfo[] cultures = Array.FindAll(CultureInfo.GetCultures(CultureTypes.SpecificCultures),
                                 culture => culture.Name.StartsWith(name + "-", StringComparison.OrdinalIgnoreCase));
        // Create an array of NumberFormatInfo properties
        PropertyInfo[] properties = typeof(NumberFormatInfo).GetProperties(BindingFlags.Instance | BindingFlags.Public);
        bool hasOneMatch = false;

        foreach (var ci in cultures)
        {
            bool match = true;
            // Get the NumberFormatInfo for a specific culture.
            NumberFormatInfo specificNfi = ci.NumberFormat;
            // Compare the property values of the two.
            foreach (var prop in properties)
            {
                // We're not interested in the value of IsReadOnly.
                if (prop.Name == "IsReadOnly") continue;

                // For arrays, iterate the individual elements to see if they are the same.
                if (prop.PropertyType.IsArray)
                {
                    IList nList = (IList)prop.GetValue(nfi, null);
                    IList sList = (IList)prop.GetValue(specificNfi, null);
                    if (nList.Count != sList.Count)
                    {
                        match = false;
                        break;
                    }

                    for (int ctr = 0; ctr < nList.Count; ctr++)
                    {
                        if (!nList[ctr].Equals(sList[ctr]))
                        {
                            match = false;
                            break;
                        }
                    }
                }
                else if (!prop.GetValue(specificNfi).Equals(prop.GetValue(nfi)))
                {
                    match = false;
                    break;
                }
            }
            if (match)
            {
                Console.WriteLine("NumberFormatInfo object for '{0}' matches '{1}'",
                                          name, ci.Name);
                hasOneMatch = true;
            }
        }
        if (!hasOneMatch)
            Console.WriteLine("NumberFormatInfo object for '{0}' --> No Match", name);

        Console.WriteLine();
    }
}

動態數據

格式化 類別所 NumberFormatInfo 提供數值的文化特性特定數據是動態的,就像 類別所提供的 CultureInfo 文化特性數據一樣。 您不應該對與特定CultureInfo對象相關聯之物件的值NumberFormatInfo穩定性進行任何假設。 只有不因文化特性及其相關聯 NumberFormatInfo 物件所提供的數據是穩定的。 基於下列原因,其他數據可以在應用程式會話之間變更,甚至是在單一會話內變更:

  • 系統更新。 貨幣符號或貨幣格式等文化喜好設定會隨著時間而變更。 發生這種情況時,Windows Update 會包含特定文化特性屬性值的變更 NumberFormatInfo

  • 取代文化特性。 類別 CultureAndRegionInfoBuilder 可用來取代現有文化特性的數據。

  • 屬性值的串聯變更。 一些文化特性相關的屬性可以在運行時間變更,這反過來又會導致 NumberFormatInfo 數據變更。 例如,您可以透過程序設計方式或透過使用者動作來變更目前的文化特性。 發生這種情況時, NumberFormatInfo 屬性所傳 CurrentInfo 回的物件會變更為與目前文化特性相關聯的物件。

  • 用戶喜好設定。 您的應用程式使用者可能會透過 控制台 中的區域和語言選項,覆寫與目前系統文化特性相關聯的某些值。 例如,使用者可能會選擇不同的貨幣符號或不同的小數分隔符符號。 CultureInfo.UseUserOverride如果 屬性設定為 true (其預設值),也會從用戶設定擷取 物件的屬性NumberFormatInfo

建立物件時,會初始化物件的所有 NumberFormatInfo 用戶可覆寫屬性。 仍有不一致的可能性,因為物件建立和使用者覆寫程式都不可部分完成,而且相關值可能會在物件建立期間變更。 不過,這些不一致的情況應該非常罕見。

您可以控制使用者覆寫是否反映在 NumberFormatInfo 代表與目前文化特性相同文化特性的物件中。 下表列出可以擷取物件的方式 NumberFormatInfo ,並指出產生的物件是否反映使用者覆寫。

CultureInfo 和 NumberFormatInfo 物件的來源 反思 用戶覆寫
CultureInfo.CurrentCulture.NumberFormat 屬性 Yes
NumberFormatInfo.CurrentInfo 屬性 Yes
CultureInfo.CreateSpecificCulture 方法 Yes
CultureInfo.GetCultureInfo 方法 No
CultureInfo(String) 建構函式 Yes
CultureInfo.CultureInfo(String, Boolean) 建構函式 取決於參數的值useUserOverride

除非有令人信服的理由這樣做,否則當您在 NumberFormatInfo 用戶端應用程式中使用 物件來格式化和剖析使用者輸入或顯示數值數據時,您應該遵守使用者覆寫。 對於伺服器應用程式或自動應用程式,您不應該遵守使用者覆寫。 不過,如果您要明確或隱含地使用 NumberFormatInfo 物件,以字串形式保存數值數據,則應該使用 NumberFormatInfo 反映不因文化特性之格式設定慣例的物件,或者您應該指定不論文化特性為何使用的自定義數值格式字符串。

IFormatProvider、NumberFormatInfo 和數值格式設定

NumberFormatInfo物件會以隱含或明確方式用於所有數值格式設定作業。 這些包括呼叫下列方法:

所有數值格式設定作業都會使用 實 IFormatProvider 作。 介面 IFormatProvider 包含單一方法 GetFormat(Type)。 這是一種回呼方法,傳遞 Type 物件,表示提供格式資訊所需的類型。 如果方法無法提供型別的實體,則方法會負責傳回該類型的 null實體或 。 .NET 提供兩 IFormatProvider 個格式化數字的實作:

如果未明確將實 IFormatProvider 作提供給格式化方法, CultureInfo 則會使用表示目前文化特性的屬性所 CultureInfo.CurrentCulture 傳回的物件。

下列範例會藉由定義自定義IFormatProvider實作,說明介面與NumberFormatInfo類別在格式化作業中的關聯IFormatProvider性。 其 GetFormat 方法會顯示格式化作業所要求的物件類型名稱。 如果介面要求 NumberFormatInfo 對象,這個方法會提供 NumberFormatInfo 目前文化特性的物件。 如範例的輸出所示, Decimal.ToString(IFormatProvider) 方法會要求 NumberFormatInfo 物件提供格式化資訊,而 String.Format(IFormatProvider, String, Object[]) 方法會要求 NumberFormatInfoDateTimeFormatInfo 物件以及 ICustomFormatter 實作。

using System;
using System.Globalization;

public class CurrentCultureFormatProvider : IFormatProvider
{
    public Object GetFormat(Type formatType)
    {
        Console.WriteLine("Requesting an object of type {0}",
                          formatType.Name);
        if (formatType == typeof(NumberFormatInfo))
            return NumberFormatInfo.CurrentInfo;
        else if (formatType == typeof(DateTimeFormatInfo))
            return DateTimeFormatInfo.CurrentInfo;
        else
            return null;
    }
}

public class FormatProviderEx
{
    public static void Main()
    {
        Decimal amount = 1203.541m;
        string value = amount.ToString("C2", new CurrentCultureFormatProvider());
        Console.WriteLine(value);
        Console.WriteLine();
        string composite = String.Format(new CurrentCultureFormatProvider(),
                                         "Date: {0}   Amount: {1}   Description: {2}",
                                         DateTime.Now, 1264.03m, "Service Charge");
        Console.WriteLine(composite);
        Console.WriteLine();
    }
}
// The example displays output like the following:
//    Requesting an object of type NumberFormatInfo
//    $1,203.54
//
//    Requesting an object of type ICustomFormatter
//    Requesting an object of type DateTimeFormatInfo
//    Requesting an object of type NumberFormatInfo
//    Date: 11/15/2012 2:00:01 PM   Amount: 1264.03   Description: Service Charge

如果未在數值格式方法呼叫中明確提供實 IFormatProvider 作,方法會呼叫 CultureInfo.CurrentCulture.GetFormat 方法,此方法會 NumberFormatInfo 傳回對應至目前文化特性的物件。

格式化字串和 NumberFormatInfo 屬性

每個格式化作業都會使用標準或自定義數值格式字串,從數位產生結果字串。 在某些情況下,使用格式字串來產生結果字串是明確的,如下列範例所示。 此程式代碼會呼叫 方法, Decimal.ToString(IFormatProvider) 使用 en-US 文化特性的格式慣例,將值轉換成 Decimal 數個不同的字串表示法。

using System;
using System.Globalization;

public class PropertiesEx1
{
    public static void Main()
    {
        string[] formatStrings = { "C2", "E1", "F", "G3", "N",
                                 "#,##0.000", "0,000,000,000.0##" };
        CultureInfo culture = CultureInfo.CreateSpecificCulture("en-US");
        Decimal[] values = { 1345.6538m, 1921651.16m };

        foreach (var value in values)
        {
            foreach (var formatString in formatStrings)
            {
                string resultString = value.ToString(formatString, culture);
                Console.WriteLine("{0,-18} -->  {1}", formatString, resultString);
            }
            Console.WriteLine();
        }
    }
}
// The example displays the following output:
//       C2                 -->  $1,345.65
//       E1                 -->  1.3E+003
//       F                  -->  1345.65
//       G3                 -->  1.35E+03
//       N                  -->  1,345.65
//       #,##0.000          -->  1,345.654
//       0,000,000,000.0##  -->  0,000,001,345.654
//
//       C2                 -->  $1,921,651.16
//       E1                 -->  1.9E+006
//       F                  -->  1921651.16
//       G3                 -->  1.92E+06
//       N                  -->  1,921,651.16
//       #,##0.000          -->  1,921,651.160
//       0,000,000,000.0##  -->  0,001,921,651.16

在其他情況下,使用格式字串是隱含的。 例如,在下列方法呼叫預設或無 Decimal.ToString() 參數方法時,實例的值 Decimal 會使用一般 (“G”) 格式規範和目前文化特性的慣例來格式化,在此案例中為 en-US 文化特性。

using System;

public class PropertiesEx2
{
    public static void Main()
    {
        Decimal[] values = { 1345.6538m, 1921651.16m };

        foreach (var value in values)
        {
            string resultString = value.ToString();
            Console.WriteLine(resultString);
            Console.WriteLine();
        }
    }
}
// The example displays the following output:
//       1345.6538
//
//       1921651.16

每個標準數值格式字串都會使用一或多個 NumberFormatInfo 屬性來判斷結果字串中使用的模式或符號。 同樣地,除了 「0」 和 「#」 以外的每個自定義數值格式規範,都會在屬性所 NumberFormatInfo 定義的結果字串中插入符號。 下表列出標準和自定義數值格式規範及其相關聯的 NumberFormatInfo 屬性。 若要變更特定文化特性的結果字串外觀,請參閱 Modify NumberFormatInfo屬性 一節。 如需使用這些格式規範的詳細資訊,請參閱 標準數值格式字串自定義數值格式字串

格式規範 相關聯的屬性
“C” 或 “c” (貨幣格式規範) CurrencyDecimalDigits,以定義小數點數的預設數目。

CurrencyDecimalSeparator 定義小數分隔符號。

CurrencyGroupSeparator,以定義群組或千位分隔符。

CurrencyGroupSizes,以定義整數群組的大小。

CurrencyNegativePattern,以定義負貨幣值的模式。

CurrencyPositivePattern,以定義正貨幣值的模式。

CurrencySymbol,以定義貨幣符號。

NegativeSign 定義負號。
“D” 或 “d” (十進位格式規範) NegativeSign 定義負號。
“E” 或 “e” (指數或科學格式規範) NegativeSign,以在mantissa和指數中定義負號符號。

NumberDecimalSeparator 定義小數分隔符號。

PositiveSign,以在指數中定義正負號符號。
“F” 或 “f” (固定點格式規範) NegativeSign 定義負號。

NumberDecimalDigits,以定義小數點數的預設數目。

NumberDecimalSeparator 定義小數分隔符號。
“G” 或 “g” (一般格式規範) NegativeSign 定義負號。

NumberDecimalSeparator 定義小數分隔符號。

PositiveSign,以指數格式定義結果字串的正負號符號。
“N” 或 “n” (數位格式規範) NegativeSign 定義負號。

NumberDecimalDigits,以定義小數點數的預設數目。

NumberDecimalSeparator 定義小數分隔符號。

NumberGroupSeparator,以定義群組分隔符 (千個) 符號。

NumberGroupSizes,以定義群組中的整數位數。

NumberNegativePattern,以定義負值的格式。
“P” 或 “p” (百分比格式規範) NegativeSign 定義負號。

PercentDecimalDigits,以定義小數點數的預設數目。

PercentDecimalSeparator 定義小數分隔符號。

PercentGroupSeparator,以定義群組分隔符號。

PercentGroupSizes,以定義群組中的整數位數。

PercentNegativePattern,以定義負值的百分比符號和負號的位置。

PercentPositivePattern,以定義正值之百分比符號的位置。

PercentSymbol,以定義百分比符號。
“R” 或 “r” (往返格式規範) NegativeSign 定義負號。

NumberDecimalSeparator 定義小數分隔符號。

PositiveSign,以在指數中定義正負號符號。
“X” 或 “x” (十六進位格式規範) 無。
"."(小數點自定義格式規範) NumberDecimalSeparator 定義小數分隔符號。
“,”(群組分隔符自定義格式規範) NumberGroupSeparator,以定義群組 (thousands) 分隔符符號。
%“ (百分比佔位元元自訂格式規範) PercentSymbol,以定義百分比符號。
“•”(每千米佔位符自定義格式規範) PerMilleSymbol,以定義每千米符號。
“E” (指數表示法自定義格式規範) NegativeSign,以在mantissa和指數中定義負號符號。

PositiveSign,以在指數中定義正負號符號。

請注意,類別 NumberFormatInfo 包含屬性 NativeDigits ,指定特定文化特性所使用的基底 10 位數。 不過,屬性不會用於格式化作業;結果字串中只會使用基本拉丁數位 0 (U+0030) 到 9 (U+0039)。 此外,針對 SinglePositiveInfinity和的NaNDoubleNegativeInfinity值,結果字串會分別包含 、PositiveInfinitySymbol、 和 NegativeInfinitySymbol 屬性所NaNSymbol定義的符號。

修改 NumberFormatInfo 屬性

您可以修改 物件的屬性 NumberFormatInfo ,以自定義數值格式設定作業所產生的結果字串。 若要這樣做:

  1. 建立您想要修改其格式慣例的物件 NumberFormatInfo 讀取/寫入複本。 如需詳細資訊,請參閱 具現化 NumberFormatInfo 對象 一節。

  2. 修改用來產生所需結果字串的屬性或屬性。 如需格式化方法 NumberFormatInfo 如何使用屬性來定義結果字串的資訊,請參閱 格式化字串和 NumberFormatInfo 屬性 一節。

  3. 使用自訂 NumberFormatInfo 物件做為 IFormatProvider 呼叫格式化方法中的自變數。

注意

您不必在每次啟動應用程式時動態修改文化特性的屬性值,而是使用 CultureAndRegionInfoBuilder 類別來定義自定義文化特性(具有唯一名稱和補充現有文化特性的文化特性)或取代文化特性(使用而非特定文化特性的文化特性)。

下列各節提供一些範例。

修改貨幣符號和模式

下列範例會 NumberFormatInfo 修改 物件,此物件代表 en-US 文化特性的格式設定慣例。 它會將 ISO-4217 貨幣符號指派給 屬性, CurrencySymbol 並定義貨幣值的模式,其中包含貨幣符號後面接著空格和數值。

using System;
using System.Globalization;

public class Example
{
    public static void Main()
    {
        // Retrieve a writable NumberFormatInfo object.
        CultureInfo enUS = CultureInfo.CreateSpecificCulture("en-US");
        NumberFormatInfo nfi = enUS.NumberFormat;

        // Use the ISO currency symbol instead of the native currency symbol.
        nfi.CurrencySymbol = (new RegionInfo(enUS.Name)).ISOCurrencySymbol;
        // Change the positive currency pattern to <code><space><value>.
        nfi.CurrencyPositivePattern = 2;
        // Change the negative currency pattern to <code><space><sign><value>.
        nfi.CurrencyNegativePattern = 12;

        // Produce the result strings by calling ToString.
        Decimal[] values = { 1065.23m, 19.89m, -.03m, -175902.32m };
        foreach (var value in values)
            Console.WriteLine(value.ToString("C", enUS));

        Console.WriteLine();

        // Produce the result strings by calling a composite formatting method.
        foreach (var value in values)
            Console.WriteLine(String.Format(enUS, "{0:C}", value));
    }
}
// The example displays the following output:
//       USD 1,065.23
//       USD 19.89
//       USD -0.03
//       USD -175,902.32
//
//       USD 1,065.23
//       USD 19.89
//       USD -0.03
//       USD -175,902.32

格式化國家識別碼

許多國家識別編號只包含數位,因此可以藉由修改 對象的屬性 NumberFormatInfo 來輕鬆地格式化。 例如,美國 中的社會保險號碼是由9位數所組成,如下所示:XXX-XX-XXXX。 下列範例假設社會安全號碼會儲存為整數值,並適當地格式化它們。

using System;
using System.Globalization;

public class CustomizeSSNEx
{
    public static void Main()
    {
        // Instantiate a read-only NumberFormatInfo object.
        CultureInfo enUS = CultureInfo.CreateSpecificCulture("en-US");
        NumberFormatInfo nfi = enUS.NumberFormat;

        // Modify the relevant properties.
        nfi.NumberGroupSeparator = "-";
        nfi.NumberGroupSizes = new int[] { 3, 2, 4 };
        nfi.NumberDecimalDigits = 0;

        int[] ids = { 111223333, 999776666 };

        // Produce the result string by calling ToString.
        foreach (var id in ids)
            Console.WriteLine(id.ToString("N", enUS));

        Console.WriteLine();

        // Produce the result string using composite formatting.
        foreach (var id in ids)
            Console.WriteLine(String.Format(enUS, "{0:N}", id));
    }
}
// The example displays the following output:
//       1112-23-333
//       9997-76-666
//
//       1112-23-333
//       9997-76-666

剖析數值字串

剖析牽涉到將數位的字串表示轉換成數位。 .NET 中的每個數值類型都包含兩個多載剖析方法: ParseTryParse。 方法 Parse 會將字串轉換成數位,並在轉換失敗時擲回例外狀況。 方法 TryParse 會將字串轉換成數位、將數位指派給 out 自變數,並傳 Boolean 回值,指出轉換是否成功。

剖析方法會隱含或明確地使用 NumberStyles 列舉值來判斷如果剖析作業成功,可以在字元串中顯示哪些樣式專案(例如群組分隔符、小數分隔符或貨幣符號)。 如果未在 NumberStyles 方法呼叫中提供值,則預設值為 NumberStyles 包含 FloatAllowThousands 旗標的值,指定剖析的字串可以包含群組符號、小數分隔符、負號和空格符,或者它可以是指數表示法中數位的字元串表示法。

剖析方法也會隱含或明確使用 NumberFormatInfo 物件,定義可剖析之字串中可能發生的特定符號和模式。 NumberFormatInfo如果未提供物件,則預設為NumberFormatInfo目前文化特性的 。 如需剖析的詳細資訊,請參閱個別剖析方法,例如 Int16.Parse(String)Int32.Parse(String, NumberStyles)、、Int64.Parse(String, IFormatProvider)Decimal.Parse(String, NumberStyles, IFormatProvider)Double.TryParse(String, Double)BigInteger.TryParse(String, NumberStyles, IFormatProvider, BigInteger)

下列範例說明剖析字串的文化特性。 它會嘗試使用 en-US、fr-FR 和不因文化特性的慣例來剖析包含數千個分隔符的字串。 字串,包含逗號做為群組分隔符,而句點作為小數分隔符在fr-FR文化特性中無法剖析,而空格符為群組分隔符的字元串,而以逗號做為小數分隔符的字串則無法在 en-US 和非變異文化特性中剖析。

using System;
using System.Globalization;

public class ParseEx1
{
    public static void Main()
    {
        String[] values = { "1,034,562.91", "9 532 978,07" };
        String[] cultureNames = { "en-US", "fr-FR", "" };

        foreach (var value in values)
        {
            foreach (var cultureName in cultureNames)
            {
                CultureInfo culture = CultureInfo.CreateSpecificCulture(cultureName);
                String name = culture.Name == "" ? "Invariant" : culture.Name;
                try
                {
                    Decimal amount = Decimal.Parse(value, culture);
                    Console.WriteLine("'{0}' --> {1} ({2})", value, amount, name);
                }
                catch (FormatException)
                {
                    Console.WriteLine("'{0}': FormatException ({1})",
                                      value, name);
                }
            }
            Console.WriteLine();
        }
    }
}
// The example displays the following output:
//       '1,034,562.91' --> 1034562.91 (en-US)
//       '1,034,562.91': FormatException (fr-FR)
//       '1,034,562.91' --> 1034562.91 (Invariant)
//
//       '9 532 978,07': FormatException (en-US)
//       '9 532 978,07' --> 9532978.07 (fr-FR)
//       '9 532 978,07': FormatException (Invariant)

剖析通常發生在兩個內容中:

  • 做為將使用者輸入轉換成數值而設計的作業。

  • 做為設計來回數值的作業;也就是說,若要還原串行化先前串行化為字串的數值。

下列各節會更詳細地討論這兩項作業。

剖析使用者字串

當您剖析使用者輸入的數值字串時,應該一律具現化 NumberFormatInfo 反映使用者文化設定的物件。 如需如何具現化 NumberFormatInfo 反映使用者自定義之物件的資訊,請參閱 動態數據 一節。

下列範例說明剖析作業之間的差異,該作業反映使用者文化特性設定,以及未反映的作業。 在此情況下,默認系統文化特性為 en-US,但使用者已將 “,”定義為十進位符號和 “.” 作為 控制台、地區和語言中的群組分隔符。 通常,這些符號會在預設的 en-US 文化特性中反轉。 當使用者輸入反映使用者設定的字串,而且字串是由 NumberFormatInfo 也會反映使用者設定(覆寫)的物件剖析時,剖析作業會傳回正確的結果。 不過,當字串由 NumberFormatInfo 反映標準 en-US 文化設定的物件剖析時,會錯誤群組分隔符的逗號符號,並傳回不正確的結果。

using System;
using System.Globalization;

public class ParseUserEx
{
    public static void Main()
    {
        CultureInfo stdCulture = CultureInfo.GetCultureInfo("en-US");
        CultureInfo custCulture = CultureInfo.CreateSpecificCulture("en-US");

        String value = "310,16";
        try
        {
            Console.WriteLine("{0} culture reflects user overrides: {1}",
                              stdCulture.Name, stdCulture.UseUserOverride);
            Decimal amount = Decimal.Parse(value, stdCulture);
            Console.WriteLine("'{0}' --> {1}", value, amount.ToString(CultureInfo.InvariantCulture));
        }
        catch (FormatException)
        {
            Console.WriteLine("Unable to parse '{0}'", value);
        }
        Console.WriteLine();

        try
        {
            Console.WriteLine("{0} culture reflects user overrides: {1}",
                              custCulture.Name, custCulture.UseUserOverride);
            Decimal amount = Decimal.Parse(value, custCulture);
            Console.WriteLine("'{0}' --> {1}", value, amount.ToString(CultureInfo.InvariantCulture));
        }
        catch (FormatException)
        {
            Console.WriteLine("Unable to parse '{0}'", value);
        }
    }
}
// The example displays the following output:
//       en-US culture reflects user overrides: False
//       '310,16' --> 31016
//
//       en-US culture reflects user overrides: True
//       '310,16' --> 310.16

串行化和還原串行化數值數據

當數值數據以字串格式串行化,稍後還原串行化和剖析時,應該使用不因文化特性的慣例來產生和剖析字串串。 格式設定和剖析作業絕不應反映特定文化特性的慣例。 如果使用文化特性特定的設定,數據可移植性會受到嚴格限制;它只能在文化特性特定設定與串行化線程的線程上成功還原串行化。 在某些情況下,這表示數據甚至無法在串行化所在的相同系統上成功還原串行化。

下列範例說明違反此原則時可能發生的情況。 當目前線程使用 en-US 文化特性的特定文化特性設定時,陣列中的浮點值會轉換成字串。 然後,數據會由使用 pt-BR 文化特性特定設定的線程剖析。 在此情況下,雖然每個剖析作業都成功,但數據不會成功往返,而且數據損毀就會發生。 在其他情況下,剖析作業可能會失敗,而且 FormatException 可能會擲回例外狀況。

using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Threading;

public class ParsePersistedEx
{
    public static void Main()
    {
        CultureInfo.CurrentCulture = CultureInfo.CreateSpecificCulture("en-US");
        PersistData();

        CultureInfo.CurrentCulture = CultureInfo.CreateSpecificCulture("pt-BR");
        RestoreData();
    }

    private static void PersistData()
    {
        // Define an array of floating-point values.
        Double[] values = { 160325.972, 8631.16, 1.304e5, 98017554.385,
                          8.5938287084321676e94 };
        Console.WriteLine("Original values: ");
        foreach (var value in values)
            Console.WriteLine(value.ToString("R", CultureInfo.InvariantCulture));

        // Serialize an array of doubles to a file
        StreamWriter sw = new StreamWriter(@".\NumericData.bin");
        for (int ctr = 0; ctr < values.Length; ctr++)
        {
            sw.Write(values[ctr].ToString("R"));
            if (ctr < values.Length - 1) sw.Write("|");
        }
        sw.Close();
        Console.WriteLine();
    }

    private static void RestoreData()
    {
        // Deserialize the data
        StreamReader sr = new StreamReader(@".\NumericData.bin");
        String data = sr.ReadToEnd();
        sr.Close();

        String[] stringValues = data.Split('|');
        List<Double> newValueList = new List<Double>();

        foreach (var stringValue in stringValues)
        {
            try
            {
                newValueList.Add(Double.Parse(stringValue));
            }
            catch (FormatException)
            {
                newValueList.Add(Double.NaN);
            }
        }

        Console.WriteLine("Restored values:");
        foreach (var newValue in newValueList)
            Console.WriteLine(newValue.ToString("R", NumberFormatInfo.InvariantInfo));
    }
}
// The example displays the following output:
//       Original values:
//       160325.972
//       8631.16
//       130400
//       98017554.385
//       8.5938287084321671E+94
//
//       Restored values:
//       160325972
//       863116
//       130400
//       98017554385
//       8.5938287084321666E+110