語言

NumberFormatInfo 類別

定義

提供針對特定文化的資訊,用於格式化與解析數值。

public ref class NumberFormatInfo sealed : IFormatProvider
public ref class NumberFormatInfo sealed : ICloneable, IFormatProvider
public sealed class NumberFormatInfo : IFormatProvider
public sealed class NumberFormatInfo : ICloneable, IFormatProvider
[System.Serializable]
public sealed class NumberFormatInfo : ICloneable, IFormatProvider
[System.Serializable]
[System.Runtime.InteropServices.ComVisible(true)]
public sealed class NumberFormatInfo : ICloneable, IFormatProvider
type NumberFormatInfo = class
    interface IFormatProvider
type NumberFormatInfo = class
    interface ICloneable
    interface IFormatProvider
[<System.Serializable>]
type NumberFormatInfo = class
    interface ICloneable
    interface IFormatProvider
[<System.Serializable>]
[<System.Runtime.InteropServices.ComVisible(true)>]
type NumberFormatInfo = class
    interface ICloneable
    interface IFormatProvider
Public NotInheritable Class NumberFormatInfo
Implements IFormatProvider
Public NotInheritable Class NumberFormatInfo
Implements ICloneable, IFormatProvider
繼承
NumberFormatInfo
屬性
實作

備註

類別 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 作業系統允許使用者透過 [控制面板] 中的 NumberFormatInfo 專案,修改在數值格式設定和解析作業中使用的部分 屬性值。 例如,文化特性為英文(美國)的使用者可能會選擇將貨幣值顯示為1.1美元,而不是預設值 $1.1。 以先前討論過的方法擷取的 NumberFormatInfo 物件都會反映這些使用者覆寫。 如果這樣的設計不符合需求,您可以呼叫 NumberFormatInfo 建構函式,為 CultureInfo.CultureInfo(String, Boolean) 參數提供 false 值,來建立一個 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:    {culture.Name}");
        Console.WriteLine($"User Overrides:  {culture.UseUserOverride}");
        Console.WriteLine($"Currency Symbol: {culture.NumberFormat.CurrencySymbol}\n");

        culture = new CultureInfo(CultureInfo.CurrentCulture.Name, false);
        Console.WriteLine($"Culture Name:    {culture.Name}");
        Console.WriteLine($"User Overrides:  {culture.UseUserOverride}");
        Console.WriteLine($"Currency Symbol: {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: {nfi.IsReadOnly}");

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

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

        culture = new CultureInfo("id-ID");
        nfi = culture.NumberFormat;
        Console.WriteLine($"Read-only: {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 中性 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 '{name}' matches '{ci.Name}'");
                hasOneMatch = true;
            }
        }
        if (!hasOneMatch)
            Console.WriteLine($"NumberFormatInfo object for '{name}' --> No Match");

        Console.WriteLine();
    }
}

動態數據

NumberFormatInfo 類別提供的格式化數值的文化特定數據是動態的,就像由 CultureInfo 類別提供的文化數據一樣。 您不應該對與特定NumberFormatInfo對象相關聯之物件的值CultureInfo穩定性進行任何假設。 只有由不變文化及其相關聯的 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物件。

下列範例藉由定義自訂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 {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 屬性

每個格式化作業都會使用標準或自定義數值格式字串,從數位產生結果字串。 在某些情況下,使用格式字串來產生結果字串是明確的,如下列範例所示。 此程式代碼會呼叫 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” (十六進位格式規範) None.
"."(小數點自定義格式規範) NumberDecimalSeparator,以定義小數分隔符號。
“,”(群組分隔符自定義格式規範) NumberGroupSeparator,以定義群組 (thousands) 分隔符符號。
“%” (百分比佔位符自定義格式規範) PercentSymbol,以定義百分比符號。
“‰”(每千佔位符自定義格式規範) PerMilleSymbol,以定義每千米符號。
“E” (指數表示法自定義格式規範) NegativeSign,以在mantissa和指數中定義負號符號。

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

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

修改 NumberFormatInfo 屬性

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

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

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

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

Note

您不必在每次啟動應用程式時動態修改文化特性的屬性值,而是使用 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($"'{value}' --> {amount} ({name})");
                }
                catch (FormatException)
                {
                    Console.WriteLine($"'{value}': FormatException ({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 反映使用者自定義之物件的資訊,請參閱 動態數據 一節。

以下範例說明反映使用者文化設定的剖析作業與不反映的剖析作業之間的差異。 在此情況下,預設系統文化特性是 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($"{stdCulture.Name} culture reflects user overrides: {stdCulture.UseUserOverride}");
            Decimal amount = Decimal.Parse(value, stdCulture);
            Console.WriteLine($"'{value}' --> {amount.ToString(CultureInfo.InvariantCulture)}");
        }
        catch (FormatException)
        {
            Console.WriteLine($"Unable to parse '{value}'");
        }
        Console.WriteLine();

        try
        {
            Console.WriteLine($"{custCulture.Name} culture reflects user overrides: {custCulture.UseUserOverride}");
            Decimal amount = Decimal.Parse(value, custCulture);
            Console.WriteLine($"'{value}' --> {amount.ToString(CultureInfo.InvariantCulture)}");
        }
        catch (FormatException)
        {
            Console.WriteLine($"Unable to parse '{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

範例

  The following example shows how to retrieve a <xref:System.Globalization.NumberFormatInfo> object for a corresponding <xref:System.Globalization.CultureInfo> object, and use the retrieved object to query number formatting information for the particular culture.

  :::code language="csharp" source="~/snippets/csharp/System.Globalization/NumberFormatInfo/Overview/NumberFormatInfo.cs" id="Snippet1":::
  :::code language="vb" source="~/snippets/visualbasic/System.Globalization/NumberFormatInfo/Overview/numberformatinfo.vb" id="Snippet1":::

建構函式

名稱 Description
NumberFormatInfo()

初始化一個可寫入的類別實例 NumberFormatInfo ,且與文化無關(不變)。

屬性

名稱 Description
CurrencyDecimalDigits

取得或設定貨幣價值中小數點數。

CurrencyDecimalSeparator

取得或設定該字串作為貨幣值的十進位分隔符。

CurrencyGroupSeparator

取得或設定分隔貨幣值中小數點左側數字群組的字串。

CurrencyGroupSizes

取得或設定貨幣值中每組小數點左側的數字數。

CurrencyNegativePattern

取得或設定負貨幣價值的格式模式。

CurrencyPositivePattern

取得或設定正值貨幣的格式模式。

CurrencySymbol

取得或設定該字串作為貨幣符號。

CurrentInfo

會用一個 NumberFormatInfo 只讀檔,根據當前文化格式化數值。

DigitSubstitution

取得或設定一個值,指定圖形使用者介面如何顯示數字形狀。

InvariantInfo

會得到一個只讀 NumberFormatInfo 且與文化無關(不變)的物件。

IsReadOnly

會得到一個值,表示該 NumberFormatInfo 物件是否為唯讀。

NaNSymbol

取得或設定代表 IEEE NaN(非數字)值的字串。

NativeDigits

取得或設定一個與西方數字 0 到 9 等價的本地數字串陣列。

NegativeInfinitySymbol

取得或設定代表負無限大的字串。

NegativeSign

取得或設定表示對應數字為負的字串。

NumberDecimalDigits

取得或設定使用數值的點數。

NumberDecimalSeparator

取得或設定字串作為數字中的十進位分隔符。

NumberGroupSeparator

取得或設定將數字中小數點左側數字群組分隔開的字串。

NumberGroupSizes

取得或設定每組中小數點左側的數字數。

NumberNegativePattern

取得或設定負數值的格式模式。

PercentDecimalDigits

取得或設定以百分比表示的小數點數。

PercentDecimalSeparator

取得或設定字串作為百分碼的十進位分隔符。

PercentGroupSeparator

取得或設定將小數點左側數字群組分隔成百分比的字串。

PercentGroupSizes

取得或設定每組中小數點左側的數字(百分比值)。

PercentNegativePattern

取得或設定負百分比值的格式模式。

PercentPositivePattern

取得或設定正百分比值的格式模式。

PercentSymbol

取得或設定字串作為百分比符號。

PerMilleSymbol

取得或設定字串作為千分符號。

PositiveInfinitySymbol

取得或設定代表正無限大的字串。

PositiveSign

取得或設定表示該數字為正的字串。

方法

名稱 Description
Clone()

會產生一個淺層的物件複製 NumberFormatInfo 品。

Equals(Object)

判斷指定的物件是否等於目前的物件。

(繼承來源 Object)
GetFormat(Type)

取得指定類型的物件,提供數字格式化服務。

GetHashCode()

做為預設哈希函式。

(繼承來源 Object)
GetInstance(IFormatProvider)

得到 NumberFormatInfo 與指定 IFormatProvider相關聯的 。

GetType()

取得目前實例的 Type

(繼承來源 Object)
MemberwiseClone()

建立目前 Object的淺層複本。

(繼承來源 Object)
ReadOnly(NumberFormatInfo)

傳回只讀 NumberFormatInfo 包裝函式。

ToString()

傳回表示目前 物件的字串。

(繼承來源 Object)

適用於

另請參閱