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 объект доступен только для чтения.

  • Путем извлечения 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 долларов США вместо значения по умолчанию $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 и numeric

NumberFormatInfoОбъект используется неявно или явно во всех операциях числового форматирования. К ним относятся вызовы следующих методов:

Все операции форматирования чисел используют 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

Каждая операция форматирования использует стандартную или настраиваемую строку числового формата для получения результирующей строки из числа. В некоторых случаях использование строки форматирования для создания результирующей строки является явной, как показано в следующем примере. Этот код вызывает Decimal.ToString(IFormatProvider) метод для преобразования Decimal значения в число различных строковых представлений с помощью соглашений о форматировании языка и региональных параметров en-US.

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, чтобы определить символ отрицательного знака в мантиссае и экспоненте.

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 объекта, чтобы настроить результирующую строку, полученную при выполнении операции форматирования чисел. Для этого выполните следующие действия.

  1. Создайте копию объекта, предназначенного для чтения и записи NumberFormatInfo , соглашения о форматировании которого необходимо изменить. Дополнительные сведения см. в разделе Создание экземпляра объекта NumberFormatInfo .

  2. Измените свойство или свойства, которые используются для получения требуемой результирующей строки. Сведения о том, как методы форматирования используют NumberFormatInfo свойства для определения результирующих строк, см. в разделе Формат строк и свойства NumberFormatInfo .

  3. Используйте пользовательский NumberFormatInfo объект IFormatProvider в качестве аргумента в вызовах методов форматирования.

Примечание

Вместо динамического изменения значений свойств языка и региональных параметров при каждом запуске приложения можно использовать CultureAndRegionInfoBuilder класс для определения настраиваемого языка и региональных параметров (языка и региональных параметров с уникальным именем, дополняющих существующие культуры) или замещающего языка и региональных параметров (используется вместо конкретного языка и региональных параметров).

В следующих разделах приводятся некоторые примеры.

Изменение символа валюты и шаблона

В следующем примере изменяется NumberFormatInfo объект, представляющий соглашения о форматировании для языка и региональных параметров en-US. Он присваивает свойству символ валюты ISO-4217 CurrencySymbol и определяет шаблон для денежных значений, состоящий из символа валюты, за которым следует пробел и числовое значение.

using System;
using System.Globalization;

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

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

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

      Console.WriteLine();

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

Применяется к

См. также раздел