NumberFormatInfo 类
定义
重要
一些信息与预发行产品相关,相应产品在发行之前可能会进行重大修改。 对于此处提供的信息,Microsoft 不作任何明示或暗示的担保。
提供用于对数字值进行格式设置和分析的区域性特定信息。
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 对象是只读的。
通过 CultureInfo 从属性中检索表示当前区域性的对象 CultureInfo.CurrentCulture ,并 CultureInfo 从其属性中检索该对象 CultureInfo.NumberFormat 。
通过检索 NumberFormatInfo
static
(Shared
在 Visual Basic) 属性中返回的对象 CurrentInfo 。通过 GetInstance 使用 CultureInfo 表示当前区域性的对象调用方法。
下面的示例使用这三种方法来创建 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 上一代码示例中所述的任何方法检索对象,并 Clone 对返回的对象调用方法 NumberFormatInfo 。 这会创建原始对象的副本 NumberFormatInfo ,但其 IsReadOnly 属性为
false
。通过调用 CultureInfo.CreateSpecificCulture 方法来创建一个 CultureInfo 表示当前区域性的对象,然后使用其 CultureInfo.NumberFormat 属性来检索该 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 USD,而不是默认值 $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.DateTimeFormat CultureInfo.NumberFormat CultureInfo.TextInfo 还会从用户设置中检索属性、和。 如果用户设置与对象关联的区域性不兼容 CultureInfo (例如,如果所选日历不是属性) 列出的日历之一 OptionalCalendars ,则方法的结果和属性的值是不确定的。
实例化固定区域性的 NumberFormatInfo 对象
固定区域性表示不区分区域性的区域性。 它基于英语语言,但不是在任何特定的英语国家/地区。 尽管特定区域性的数据可以是动态的,并且可以更改以反映新的区域性约定或用户首选项,但固定区域性的数据不会更改。 一个 NumberFormatInfo 对象,该对象表示固定区域性的格式设置约定,可用于在这些操作中,结果字符串不应因区域性而异。
可以 NumberFormatInfo 通过以下方式实例化表示固定区域性的格式设置约定的对象:
通过检索属性的值 InvariantInfo 。 返回的 NumberFormatInfo 对象是只读的。
通过 CultureInfo.NumberFormat 从属性返回的对象中检索属性的值 CultureInfo CultureInfo.InvariantCulture 。 返回的 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 通过以下方式实例化表示特定区域性的格式设置约定的对象:
通过调用 CultureInfo.GetCultureInfo(String) 方法并检索返回 CultureInfo 对象的属性的值 NumberFormat 。 返回的 NumberFormatInfo 对象是只读的。
通过向 CultureInfo 静态方法传递表示要检索其对象的区域性的对象 NumberFormatInfo GetInstance 。 返回的 NumberFormatInfo 对象是可读/写的。
通过调用 CultureInfo.CreateSpecificCulture 方法并检索返回 CultureInfo 对象的属性的值 NumberFormat 。 返回的 NumberFormatInfo 对象是可读/写的。
通过调用某个 CultureInfo.CultureInfo 类构造函数并检索返回 CultureInfo 对象的属性的值 NumberFormat 。 返回的 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 异常。
但是,因为它与特定的国家/地区无关,所以非特定区域性缺少区域性特定的格式设置信息。 NumberFormatInfo.NET Framework 返回一个 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 。 不应对 NumberFormatInfo 与特定对象关联的对象的值的稳定性做出任何假设 CultureInfo 。 只有固定区域性提供的数据及其关联的对象才 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对象在所有数值格式设置操作中隐式或显式使用。 其中包括对以下方法的调用:
所有数字格式设置方法,如 Int32.ToString Double.ToString 、 和 Convert.ToString(Int32) 。
主要的复合格式设置方法 String.Format 。
其他复合格式设置方法,如 Console.WriteLine(String, Object[]) 和 StringBuilder.AppendFormat(String, Object[]) 。
所有数字格式设置操作都使用 IFormatProvider 实现。 接口 IFormatProvider 包括单个方法 GetFormat(Type) 。 这是一种回调方法,它传递表示提供格式设置信息 Type 所需的类型的 对象。 方法负责返回该类型的实例,如果无法提供该类型的实例,则返回 null
。 该.NET Framework提供了 IFormatProvider 两种用于设置数字格式的实现:
类 CultureInfo ,表示特定国家/地区 (特定区域性或特定语言) 。 在数值格式设置操作中, CultureInfo.GetFormat 方法 NumberFormatInfo 返回与其 属性关联的 CultureInfo.NumberFormat 对象。
NumberFormatInfo类,提供有关其关联区域性的格式设置约定的信息。 NumberFormatInfo.GetFormat方法返回自身的实例。
如果未向格式设置方法显式提供实现,则使用 由表示当前区域性的 属性 IFormatProvider CultureInfo CultureInfo.CurrentCulture 返回的 对象。
下面的示例通过定义自定义实现来说明 接口和 类 IFormatProvider NumberFormatInfo 在格式设置操作中 IFormatProvider 之间的关系。 其 GetFormat 方法显示格式设置操作请求的对象的类型名称。 如果接口请求 对象 NumberFormatInfo ,则此方法为 NumberFormatInfo 当前区域性提供 对象。 如示例的输出所示, 方法请求 对象以提供格式设置信息,而 方法请求 和 对象 Decimal.ToString(IFormatProvider) NumberFormatInfo 以及 String.Format(IFormatProvider, String, Object[]) NumberFormatInfo DateTimeFormatInfo 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 属性
每个格式设置操作都使用标准或自定义数字格式字符串从数字生成结果字符串。 在某些情况下,使用格式字符串生成结果字符串是显式的,如以下示例所示。 此代码调用 方法,使用 en-US 区域性的格式设置约定将值转换为多个不同的 Decimal.ToString(IFormatProvider) 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() ("G") 格式说明方法和当前区域性的约定(本例中为 en-US 区域性)格式化实例的值。 Decimal
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,用于定义底数和指数中的负号符号。 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,用于在尾数和指数中定义负号符号。 PositiveSign,用于在指数中定义正号符号。 |
请注意, NumberFormatInfo 类包括一个 NativeDigits 属性,该属性指定特定区域性使用的10进制数字。 但是,属性不在格式设置操作中使用;结果字符串中仅使用基本拉丁数字 0 (U + 0030) 到 9 (U + 0039) 。 此外,对于 Single Double 、和的值 NaN
, PositiveInfinity
NegativeInfinity
结果字符串只包含由 NaNSymbol 、 PositiveInfinitySymbol 和属性定义的符号 NegativeInfinitySymbol 。
修改 NumberFormatInfo 属性
您可以修改对象的属性 NumberFormatInfo ,以自定义数字格式设置操作中生成的结果字符串。 要执行此操作:
创建 NumberFormatInfo 要修改其格式设置约定的对象的读/写副本。 有关详细信息,请参阅 实例化 NumberFormatInfo 对象 部分。
修改用于生成所需结果字符串的属性。 有关格式化方法如何使用 NumberFormatInfo 属性来定义结果字符串的信息,请参阅 Format String and NumberFormatInfo properties 部分。
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 中的每个数值类型包括两个重载分析方法: Parse
和 TryParse
。 Parse
方法将字符串转换为数字,并在转换失败时引发异常。 TryParse
方法将字符串转换为数字,将该数字赋给 out
参数,并返回一个 Boolean 指示转换是否成功的值。
如果分析操作成功,则解析方法隐式或显式地使用 NumberStyles 枚举值来确定哪些样式元素 (如组分隔符、十进制分隔符或货币符号) 可以在字符串中存在。 如果 NumberStyles 方法调用中没有提供值,则默认值为一个 NumberStyles 包含 Float 和标志的值,该值 AllowThousands 指定分析的字符串可以包含组符号、小数分隔符、负号和空白字符,也可以是以指数表示法表示的数字的字符串表示形式。
解析方法还可以隐式或显式地使用一个 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 and dynamic data 部分。
下面的示例说明了反映用户区域性设置的分析操作与不是的操作之间的差异。 在这种情况下,默认系统区域性为 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) |