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 对应 CultureInfo 对象的对象,并使用检索的对象查询特定区域性的数字格式信息。

using namespace System;
using namespace System::Globalization;
using namespace System::Text;

int main()
{
    StringBuilder^ builder = gcnew StringBuilder();

    // Loop through all the specific cultures known to the CLR.
    for each(CultureInfo^ culture in 
        CultureInfo::GetCultures (CultureTypes::SpecificCultures)) 
    {
        // Only show the currency symbols for cultures 
        // that speak English.
        if (culture->TwoLetterISOLanguageName == "en")
        {
            // Display the culture name and currency symbol.
            NumberFormatInfo^ numberFormat = culture->NumberFormat;
            builder->AppendFormat("The currency symbol for '{0}'"+
                "is '{1}'",culture->DisplayName,
                numberFormat->CurrencySymbol);
            builder->AppendLine();
        }
    }
    Console::WriteLine(builder);
}

// This code produces the following output.
//
// The currency symbol for 'English (United States)' is '$'
// The currency symbol for 'English (United Kingdom)' is 'Ј'
// The currency symbol for 'English (Australia)' is '$'
// The currency symbol for 'English (Canada)' is '$'
// The currency symbol for 'English (New Zealand)' is '$'
// The currency symbol for 'English (Ireland)' is '?'
// The currency symbol for 'English (South Africa)' is 'R'
// The currency symbol for 'English (Jamaica)' is 'J$'
// The currency symbol for 'English (Caribbean)' is '$'
// The currency symbol for 'English (Belize)' is 'BZ$'
// The currency symbol for 'English (Trinidad and Tobago)' is 'TT$'
// The currency symbol for 'English (Zimbabwe)' is 'Z$'
// The currency symbol for 'English (Republic of the Philippines)' is 'Php'
using System;
using System.Globalization;
using System.Text;

public sealed class App
{
    static void Main()
    {
        StringBuilder sb = new StringBuilder();

        // Loop through all the specific cultures known to the CLR.
        foreach (CultureInfo ci in CultureInfo.GetCultures(CultureTypes.SpecificCultures))
        {
            // Only show the currency symbols for cultures that speak English.
            if (ci.TwoLetterISOLanguageName != "en") continue;

            // Display the culture name and currency symbol.
            NumberFormatInfo nfi = ci.NumberFormat;
            sb.AppendFormat("The currency symbol for '{0}' is '{1}'",
                ci.DisplayName, nfi.CurrencySymbol);
            sb.AppendLine();
        }
        Console.WriteLine(sb.ToString());
    }
}

// This code produces the following output.
//
// The currency symbol for 'English (United States)' is '$'
// The currency symbol for 'English (United Kingdom)' is '£'
// The currency symbol for 'English (Australia)' is '$'
// The currency symbol for 'English (Canada)' is '$'
// The currency symbol for 'English (New Zealand)' is '$'
// The currency symbol for 'English (Ireland)' is '?'
// The currency symbol for 'English (South Africa)' is 'R'
// The currency symbol for 'English (Jamaica)' is 'J$'
// The currency symbol for 'English (Caribbean)' is '$'
// The currency symbol for 'English (Belize)' is 'BZ$'
// The currency symbol for 'English (Trinidad and Tobago)' is 'TT$'
// The currency symbol for 'English (Zimbabwe)' is 'Z$'
// The currency symbol for 'English (Republic of the Philippines)' is 'Php'
Imports System.Globalization
Imports System.Text

Public Module Example
   Public Sub Main() 
      Dim sb As New StringBuilder()

      ' Loop through all the specific cultures known to the CLR.
      For Each ci In CultureInfo.GetCultures(CultureTypes.SpecificCultures) 
         ' Only show the currency symbols for cultures that speak English.
         If ci.TwoLetterISOLanguageName <> "en" Then Continue For

         ' Display the culture name and currency symbol.
         Dim nfi As NumberFormatInfo = ci.NumberFormat
         sb.AppendFormat("The currency symbol for '{0}' is '{1}'",
                         ci.DisplayName, nfi.CurrencySymbol)
         sb.AppendLine()
      Next
      Console.WriteLine(sb.ToString())
   End Sub
End Module
' The example displays output like the following:
'       The currency symbol for 'English (United States)' is '$'
'       The currency symbol for 'English (United Kingdom)' is '£'
'       The currency symbol for 'English (Australia)' is '$'
'       The currency symbol for 'English (Canada)' is '$'
'       The currency symbol for 'English (New Zealand)' is '$'
'       The currency symbol for 'English (Ireland)' is '?'
'       The currency symbol for 'English (South Africa)' is 'R'
'       The currency symbol for 'English (Jamaica)' is 'J$'
'       The currency symbol for 'English (Caribbean)' is '$'
'       The currency symbol for 'English (Belize)' is 'BZ$'
'       The currency symbol for 'English (Trinidad and Tobago)' is 'TT$'
'       The currency symbol for 'English (Zimbabwe)' is 'Z$'
'       The currency symbol for 'English (Republic of the Philippines)' is 'Php'
'       The currency symbol for 'English (India)' is 'Rs.'
'       The currency symbol for 'English (Malaysia)' is 'RM'
'       The currency symbol for 'English (Singapore)' is '$'

注解

NumberFormatInfo 类包含格式化和分析数值时使用的区域性特定信息。 此信息包括货币符号、小数符号、组分隔符以及正号和负号的符号。

实例化 NumberFormatInfo 对象

可以实例化表示 NumberFormatInfo 当前区域性的格式约定、固定区域性、特定区域性或中性区域性的对象。

实例化当前区域性的 NumberFormatInfo 对象

可以通过以下任一 NumberFormatInfo 方式实例化当前区域性的对象。 在每种情况下,返回 NumberFormatInfo 的对象都是只读的。

以下示例使用这三种方法创建 NumberFormatInfo 表示当前区域性的格式约定的对象。 它还检索属性的值 IsReadOnly ,以说明每个对象都是只读的。

using System;
using System.Globalization;

public class Example
{
   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
Imports System.Globalization

Module Example
   Public Sub Main()
      Dim current1 As NumberFormatInfo = CultureInfo.CurrentCulture.NumberFormat
      Console.WriteLine(current1.IsReadOnly)
      
      Dim current2 As NumberFormatInfo = NumberFormatInfo.CurrentInfo
      Console.WriteLine(current2.IsReadOnly)
      
      Dim current3 As NumberFormatInfo = NumberFormatInfo.GetInstance(CultureInfo.CurrentCulture)
      Console.WriteLine(current3.IsReadOnly)
   End Sub
End Module
' The example displays the following output:
'       True
'       True
'       True

可以创建一个可 NumberFormatInfo 写对象,该对象以下列任一方式表示当前区域性的约定:

下面的示例演示了这两种实例化 NumberFormatInfo 对象的方法,并显示其 IsReadOnly 属性的值,以说明该对象不是只读的。

using System;
using System.Globalization;

public class Example
{
   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
Imports System.Globalization

Module Example
   Public Sub Main()
      Dim current1 As NumberFormatInfo = NumberFormatInfo.CurrentInfo
      current1 = CType(current1.Clone(), NumberFormatInfo)
      Console.WriteLine(current1.IsReadOnly)

      Dim culture2 As CultureInfo = CultureInfo.CreateSpecificCulture(CultureInfo.CurrentCulture.Name)
      Dim current2 As NumberFormatInfo = culture2.NumberFormat
      Console.WriteLine(current2.IsReadOnly)
   End Sub
End Module
' 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 Example
{
   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: $
Imports System.Globalization

Module Example
   Public Sub Main()
      Dim culture As CultureInfo
      Dim nfi As NumberFormatInfo
      
      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}", culture.NumberFormat.CurrencySymbol)
      Console.WriteLine()
            
      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)
   End Sub
End Module
' 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.NumberFormat并且CultureInfo.TextInfo也从用户设置中检索。 例如,如果用户设置与 (对象关联的 CultureInfo 区域性不兼容,例如,如果所选日历不是属性) 列出的 OptionalCalendars 日历之一,则方法的结果和属性的值未定义。

实例化固定区域性的 NumberFormatInfo 对象

固定区域性表示不区分区域性的文化。 它基于英语,但不基于任何特定的英语国家/地区。 虽然特定区域性的数据可以是动态的,可以更改以反映新的文化约定或用户首选项,但固定区域性的数据不会更改。 表示 NumberFormatInfo 固定区域性的格式约定的对象可用于格式设置操作,其中结果字符串不应因区域性而异。

可以通过以下方式实例化表示 NumberFormatInfo 固定区域性的格式约定的对象:

以下示例使用上述每个方法实例化 NumberFormatInfo 表示固定区域性的对象。 然后,它指示对象是否为只读对象,

using System;
using System.Globalization;

public class Example
{
   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
Imports System.Globalization

Module Example
   Public Sub Main()
      Dim nfi As NumberFormatInfo
      
      nfi = System.Globalization.NumberFormatInfo.InvariantInfo
      Console.WriteLine(nfi.IsReadOnly)               
      
      nfi = CultureInfo.InvariantCulture.NumberFormat
      Console.WriteLine(nfi.IsReadOnly)               
      
      nfi = New NumberFormatInfo()
      Console.WriteLine(nfi.IsReadOnly)               
   End Sub
End Module
' The example displays the following output:
'       True
'       True
'       False

实例化特定区域性的 NumberFormatInfo 对象

特定区域性表示在特定国家/地区说的语言。 例如,en-US 是表示美国中说英语的特定区域性,en-CA 是表示加拿大英语的特定区域性。 可以通过以下方式实例化表示 NumberFormatInfo 特定区域性的格式约定的对象:

以下示例使用这四种方法创建一个 NumberFormatInfo 对象,该对象反映了印尼 (印度尼西亚) 文化的格式设置约定。 它还指示每个对象是否为只读对象。

using System;
using System.Globalization;

public class Example
{
   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
Imports System.Globalization

Module Example
   Public Sub Main()
      Dim culture As CultureInfo
      Dim nfi As NumberFormatInfo
      
      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)
   End Sub
End Module
' 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 Framework 3.5 及更低版本中,尝试检索NumberFormatInfo反映中性区域性的格式约定的对象会NotSupportedException引发异常。

但是,由于它独立于特定的国家/地区,中性文化缺乏特定于区域性的格式信息。 .NET Framework不用泛型值填充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 Example
{
   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();
   }
}
Imports System.Collections
Imports System.Collections.Generic
Imports System.Globalization
Imports System.Reflection

Module Example
   Public Sub Main()
      ' Get all the neutral cultures
      Dim names As New List(Of String)
      Array.ForEach(CultureInfo.GetCultures(CultureTypes.NeutralCultures),
                    Sub(culture) names.Add(culture.Name))
      names.Sort()
      For Each name In names
         ' Ignore the invariant culture.
         If name = "" Then Continue For
         
         ListSimilarChildCultures(name)        
      Next
   End Sub

   Private Sub ListSimilarChildCultures(name As String)
      ' Create the neutral NumberFormatInfo object.
      Dim nfi As NumberFormatInfo = CultureInfo.GetCultureInfo(name).NumberFormat
      ' Retrieve all specific cultures of the neutral culture.
      Dim cultures() As CultureInfo = Array.FindAll(CultureInfo.GetCultures(CultureTypes.SpecificCultures), 
                               Function(culture) culture.Name.StartsWith(name + "-", StringComparison.OrdinalIgnoreCase))
      ' Create an array of NumberFormatInfo properties
      Dim properties() As PropertyInfo = GetType(NumberFormatInfo).GetProperties(BindingFlags.Instance Or BindingFlags.Public)
      Dim hasOneMatch As Boolean = False

      For Each ci In cultures
         Dim match As Boolean = True     
         ' Get the NumberFormatInfo for a specific culture.
         Dim specificNfi As NumberFormatInfo = ci.NumberFormat
         ' Compare the property values of the two.
         For Each prop In properties
            ' We're not interested in the value of IsReadOnly.     
            If prop.Name = "IsReadOnly" Then Continue For
            
            ' For arrays, iterate the individual elements to see if they are the same.
            If prop.PropertyType.IsArray Then 
               Dim nList As IList = CType(prop.GetValue(nfi, Nothing), IList)
               Dim sList As IList = CType(prop.GetValue(specificNfi, Nothing), IList)
               If nList.Count <> sList.Count Then
                  match = false
                  Exit For
               End If 

               For ctr As Integer = 0 To nList.Count - 1
                  If Not nList(ctr).Equals(sList(ctr)) 
                     match = false
                     Exit For
                  End If     
               Next
            Else If Not prop.GetValue(specificNfi).Equals(prop.GetValue(nfi))
               match = false
               Exit For   
            End If        
         Next
         If match Then
            Console.WriteLine("NumberFormatInfo object for '{0}' matches '{1}'", 
                                      name, ci.Name)
            hasOneMatch = true
         End If                                       
      Next
      If Not hasOneMatch Then
         Console.WriteLine("NumberFormatInfo object for '{0}' --> No Match", name)            
      End If
      
      Console.WriteLine()
   End Sub
End Module

NumberFormatInfo 和动态数据

用于设置类提供的 NumberFormatInfo 数值格式的区域性特定数据是动态的,就像类提供的文化数据一 CultureInfo 样。 不应对与特定CultureInfo对象关联的对象的值的NumberFormatInfo稳定性做出任何假设。 只有固定区域性提供的数据及其关联的 NumberFormatInfo 对象是稳定的。 出于以下原因,其他数据可以在应用程序会话之间更改,甚至是在单个会话中更改:

  • 系统更新。 文化偏好(如货币符号或货币格式)随时间而变化。 发生这种情况时,Windows 更新包括对特定区域性的NumberFormatInfo属性值的更改。

  • 替换区域性。CultureAndRegionInfoBuilder 类可用于替换现有区域性的数据。

  • 对属性值进行级联更改。 许多与区域性相关的属性可以在运行时更改,这反过来又会导致 NumberFormatInfo 数据发生更改。 例如,可以通过编程方式或通过用户操作更改当前区域性。 发生这种情况时, NumberFormatInfo 属性返回 CurrentInfo 的对象将更改为与当前区域性关联的对象。

  • 用户首选项。 应用程序的用户可以通过控制面板中的区域和语言选项替代与当前系统区域性关联的某些值。 例如,用户可以选择不同的货币符号或不同的小数分隔符。 如果属性 CultureInfo.UseUserOverride 设置为 true (其默认值) ,则对象的属性 NumberFormatInfo 也会从用户设置中检索。

从 .NET Framework 2.0 开始,创建对象时将初始化对象的所有用户可重写属性NumberFormatInfo。 仍然存在不一致的可能性,因为创建对象和用户替代过程都不是原子的,相关值可能会在对象创建过程中更改。 但是,这些不一致应该极其罕见。

可以控制用户替代是否反映在 NumberFormatInfo 表示与当前区域性相同的区域性的对象中。 下表列出了可以检索对象的方式 NumberFormatInfo ,并指示生成的对象是否反映用户替代。

CultureInfo 和 NumberFormatInfo 对象的源 反映用户替代
CultureInfo.CurrentCulture.NumberFormat 属性
NumberFormatInfo.CurrentInfo 属性
CultureInfo.CreateSpecificCulture 方法
CultureInfo.GetCultureInfo 方法
CultureInfo(String) 构造函数
CultureInfo.CultureInfo(String, Boolean) 构造函数 取决于参数的值useUserOverride

除非有令人信服的理由这样做,否则在客户端应用程序中使用对象来格式化和分析用户输入或显示数值数据时 NumberFormatInfo ,应遵循用户替代。 对于服务器应用程序或无人参与的应用程序,不应尊重用户替代。 但是,如果使用 NumberFormatInfo 对象显式或隐式保存字符串形式的数值数据,则应使用 NumberFormatInfo 反映固定区域性的格式约定的对象,或者应指定一个自定义数值格式字符串,无论区域性如何。

IFormatProvider、NumberFormatInfo 和数字格式

对象 NumberFormatInfo 在所有数值格式设置操作中隐式或显式使用。 其中包括对以下方法的调用:

所有数值格式设置操作都使用 IFormatProvider 实现。 接口 IFormatProvider 包含单个方法 GetFormat(Type)。 这是一种回调方法, Type 传递的对象表示提供格式设置信息所需的类型。 该方法负责返回该类型的实例,或者 null,如果无法提供该类型的实例。 .NET Framework提供了两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 Example
{
   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
Imports System.Globalization

Public Class CurrentCultureFormatProvider : Implements IFormatProvider
   Public Function GetFormat(formatType As Type) As Object _
                   Implements IFormatProvider.GetFormat
      Console.WriteLine("Requesting an object of type {0}", 
                        formatType.Name)
      If formatType Is GetType(NumberFormatInfo) Then
         Return NumberFormatInfo.CurrentInfo
      Else If formatType Is GetType(DateTimeFormatInfo) Then
         Return DateTimeFormatInfo.CurrentInfo
      Else
         Return Nothing
      End If
   End Function
End Class

Module Example
   Public Sub Main()
      Dim amount As Decimal = 1203.541d
      Dim value As String = amount.ToString("C2", New CurrentCultureFormatProvider())
      Console.WriteLine(value)
      Console.WriteLine()
      Dim composite As String = String.Format(New CurrentCultureFormatProvider, 
                                              "Date: {0}   Amount: {1}   Description: {2}",
                                              Date.Now, 1264.03d, "Service Charge")
      Console.WriteLine(composite)
      Console.WriteLine()
   End Sub
End Module
' 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 Example
{
   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
Imports System.Globalization

Module Example
   Public Sub Main()
      Dim formatStrings() As String = { "C2", "E1", "F", "G3", "N", 
                                        "#,##0.000", "0,000,000,000.0##" }
      Dim culture As CultureInfo = CultureInfo.CreateSpecificCulture("en-US")
      Dim values() As Decimal = { 1345.6538d, 1921651.16d }
      
      For Each value In values
         For Each formatString In formatStrings
            Dim resultString As String = value.ToString(formatString, culture)
            Console.WriteLine("{0,-18} -->  {1}", formatString, resultString)
         Next
         Console.WriteLine()      
      Next   
   End Sub
End Module
' 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 Example
{
   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
Module Example
   Public Sub Main()
      Dim values() As Decimal = { 1345.6538d, 1921651.16d }
      
      For Each value In values
         Dim resultString As String = value.ToString()
         Console.WriteLine(resultString)
         Console.WriteLine()      
      Next   
   End Sub
End Module
' The example displays the following output:
'       1345.6538
'       
'       1921651.16

每个标准数字格式字符串使用一个或多个 NumberFormatInfo 属性来确定结果字符串中使用的模式或符号。 同样,每个自定义数字格式说明符(“0”和“#”除外)在属性定义的 NumberFormatInfo 结果字符串中插入符号。 下表列出了标准和自定义数值格式说明符及其关联 NumberFormatInfo 属性。 若要更改特定区域性的结果字符串的外观,请参阅 “修改 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,用于定义组 (千) 分隔符。
“%” (百分比占位符自定义格式说明符) PercentSymbol,用于定义百分比符号。
每个米尔占位符自定义格式说明符 (“) PerMilleSymbol,用于定义每米符号。
“E” (指数表示法自定义格式说明符) NegativeSign,用于在 mantissa 和指数中定义负号符号。

PositiveSign,用于在指数中定义正符号。

请注意,该 NumberFormatInfo 类包含一个 NativeDigits 属性,该属性指定特定区域性使用的基 10 位数字。 但是,属性不用于格式设置操作;结果字符串中仅使用基本拉丁文数字 0 (U+0030) 到 9 (U+0039) 。 In addition, for Single and Double values of NaN, PositiveInfinity, and NegativeInfinity, the result string consists exclusively of the symbols defined by the NaNSymbol, PositiveInfinitySymbol, and NegativeInfinitySymbol properties, respectively.

修改 NumberFormatInfo 属性

可以修改对象的属性 NumberFormatInfo ,以自定义在数值格式设置操作中生成的结果字符串。 要执行此操作:

  1. 创建要修改其格式约定的对象读/写副本 NumberFormatInfo 。 有关详细信息,请参阅 实例化 NumberFormatInfo 对象 部分。

  2. 修改用于生成所需结果字符串的属性或属性。 有关如何使用 NumberFormatInfo 属性定义结果字符串的格式方法的信息,请参阅 Format 字符串和 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
Imports System.Globalization

Module Example
   Public Sub Main()
      ' Retrieve a writable NumberFormatInfo object.
      Dim enUS As CultureInfo = CultureInfo.CreateSpecificCulture("en-US")
      Dim nfi As NumberFormatInfo = 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.
      Dim values() As Decimal = { 1065.23d, 19.89d, -.03d, -175902.32d }
      For Each value In values
         Console.WriteLine(value.ToString("C", enUS))
      Next      
      Console.WriteLine()
      
      ' Produce the result strings by calling a composite formatting method.
      For Each value In values
         Console.WriteLine(String.Format(enUS, "{0:C}", value))      
      Next
   End Sub
End Module
' 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 Example
{
   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
Imports System.Globalization

Module Example
   Public Sub Main()
      ' Instantiate a read-only NumberFormatInfo object.
      Dim enUS As CultureInfo = CultureInfo.CreateSpecificCulture("en-US")
      Dim nfi As NumberFormatInfo = enUS.NumberFormat

      ' Modify the relevant properties.
      nfi.NumberGroupSeparator = "-"
      nfi.NumberGroupSizes = { 3, 2, 4}
      nfi.NumberDecimalDigits = 0
      
      Dim ids() As Integer = { 111223333, 999776666 }
      
      ' Produce the result string by calling ToString.
      For Each id In ids
         Console.WriteLine(id.ToString("N", enUS))
      Next 
      Console.WriteLine()
      
      ' Produce the result string using composite formatting.
      For Each id In ids
         Console.WriteLine(String.Format(enUS, "{0:N}", id))
      Next
   End Sub
End Module
' The example displays the following output:
'       1112-23-333
'       9997-76-666
'       
'       1112-23-333
'       9997-76-666

分析数值字符串

分析涉及将数字的字符串表示形式转换为数字。 .NET Framework中的每个数值类型都包含两个重载分析方法: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 Example
{
   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)
Imports System.Globalization

Module Example
   Public Sub Main()
      Dim values() As String = { "1,034,562.91", "9 532 978,07" }
      Dim cultureNames() As String = { "en-US", "fr-FR", "" }
      
      For Each value In values
         For Each cultureName In cultureNames
            Dim culture As CultureInfo = CultureInfo.CreateSpecificCulture(cultureName)
            Dim name As String = If(culture.Name = "", "Invariant", culture.Name)
            Try
               Dim amount As Decimal = Decimal.Parse(value, culture)
               Console.WriteLine("'{0}' --> {1} ({2})", value, amount, name)
            Catch e As FormatException
               Console.WriteLine("'{0}': FormatException ({1})",
                                 value, name)
            End Try   
         Next
         Console.WriteLine()
      Next
   End Sub
End Module
' 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 反映用户自定义项的对象的信息,请参阅 NumberFormatInfo 和动态数据 部分。

下面的示例演示了分析操作之间的差异,该操作反映了用户文化设置和未执行区域性设置的操作。 在这种情况下,默认系统区域性为 en-US,但用户已将 “,”定义为十进制符号,“.”作为控制面板、区域和语言 中的组分隔符。 通常,这些符号在默认 en-US 区域性中反转。 当用户输入反映用户设置的字符串,并且字符串由 NumberFormatInfo 同时反映用户设置的对象分析, (重写) 时,分析操作将返回正确的结果。 但是,当字符串由 NumberFormatInfo 反映标准 en-US 区域性设置的对象分析时,它会错误组分隔符的逗号符号并返回不正确的结果。

using System;
using System.Globalization;

public class Example
{
   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
Imports System.Globalization

Module Example
   Public Sub Main()
      Dim stdCulture As CultureInfo = CultureInfo.GetCultureInfo("en-US")
      Dim custCulture As CultureInfo = CultureInfo.CreateSpecificCulture("en-US") 
            
      Dim value As String = "310,16"
      Try
         Console.WriteLine("{0} culture reflects user overrides: {1}", 
                           stdCulture.Name, stdCulture.UseUserOverride)
         Dim amount As Decimal = Decimal.Parse(value, stdCulture)
         Console.WriteLine("'{0}' --> {1}", value, amount.ToString(CultureInfo.InvariantCulture))                                                                                        
      Catch e As FormatException
         Console.WriteLine("Unable to parse '{0}'", value)
      End Try   
      Console.WriteLine()
                                            
      Try
         Console.WriteLine("{0} culture reflects user overrides: {1}", 
                           custCulture.Name, custCulture.UseUserOverride)
         Dim amount As Decimal = Decimal.Parse(value, custCulture)
         Console.WriteLine("'{0}' --> {1}", value, amount.ToString(CultureInfo.InvariantCulture))                                                                                        
      Catch e As FormatException
         Console.WriteLine("Unable to parse '{0}'", value)
      End Try   
   End Sub
End Module
' 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 Example
{
   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
Imports System.Collections.Generic
Imports System.Globalization
Imports System.IO
Imports System.Threading

Module Example
   Public Sub Main()
      CultureInfo.CurrentCulture = CultureInfo.CreateSpecificCulture("en-US")
      PersistData()
      
      CultureInfo.CurrentCulture = CultureInfo.CreateSpecificCulture("pt-BR")
      RestoreData()
   End Sub
   
   Private Sub PersistData()
      ' Define an array of floating-point values.
      Dim values() As Double = { 160325.972, 8631.16, 1.304e5, 98017554.385, 
                                 8.5938287084321676e94 }
      Console.WriteLine("Original values: ")
      For Each value In values
         Console.WriteLine(value.ToString("R", CultureInfo.InvariantCulture))
      Next
         
      ' Serialize an array of doubles to a file 
      Dim sw As New StreamWriter(".\NumericData.bin")
      For ctr As Integer = 0 To values.Length - 1
         sw.Write(values(ctr).ToString("R"))
         If ctr < values.Length - 1 Then sw.Write("|")
      Next
      sw.Close()
      Console.WriteLine()
   End Sub
   
   Private Sub RestoreData()   
      ' Deserialize the data
      Dim sr AS New StreamReader(".\NumericData.bin")
      Dim data As String = sr.ReadToEnd()
      sr.Close()
      
      Dim stringValues() As String = data.Split("|"c)
      Dim newValueList As New List(Of Double)
      
      For Each stringValue In stringValues
         Try
            newValueList.Add(Double.Parse(stringValue))
         Catch e As FormatException
            newValueList.Add(Double.NaN)
         End Try   
      Next                                   

      Console.WriteLine("Restored values:")
      For Each newValue In newValueList
         Console.WriteLine(newValue.ToString("R", NumberFormatInfo.InvariantInfo))
      Next
   End Sub
End Module
' 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

构造函数

NumberFormatInfo()

初始化不依赖于区域性的(固定的)NumberFormatInfo 类的新可写实例。

属性

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

获取或设置指示关联数字是正值的字符串。

方法

Clone()

创建 NumberFormatInfo 对象的浅表副本。

Equals(Object)

确定指定对象是否等于当前对象。

(继承自 Object)
GetFormat(Type)

获取提供数字格式化服务的指定类型的对象。

GetHashCode()

作为默认哈希函数。

(继承自 Object)
GetInstance(IFormatProvider)

获取与指定 NumberFormatInfo 关联的 IFormatProvider

GetType()

获取当前实例的 Type

(继承自 Object)
MemberwiseClone()

创建当前 Object 的浅表副本。

(继承自 Object)
ReadOnly(NumberFormatInfo)

返回只读的 NumberFormatInfo 包装。

ToString()

返回表示当前对象的字符串。

(继承自 Object)

适用于

另请参阅