Porady: definiowanie i użycie niestandardowych dostawców formatu liczbowegoHow to: Define and Use Custom Numeric Format Providers

.NET Framework zapewnia szeroką kontrolę nad reprezentacją ciągu wartości liczbowych.The .NET Framework gives you extensive control over the string representation of numeric values. Program obsługuje następujące funkcje dostosowywania formatu wartości liczbowych:It supports the following features for customizing the format of numeric values:

  • Standardowe ciągi formatujące liczbę, które zapewniają wstępnie zdefiniowany zestaw formatów do konwertowania liczb na ich reprezentację w postaci ciągu.Standard numeric format strings, which provide a predefined set of formats for converting numbers to their string representation. Można ich używać z dowolną metodą formatowania liczbowego, taką jak Decimal.ToString(String), która ma parametr format.You can use them with any numeric formatting method, such as Decimal.ToString(String), that has a format parameter. Aby uzyskać szczegółowe informacje, zobacz Standardowe ciągi formatujące liczby.For details, see Standard Numeric Format Strings.

  • Niestandardowe ciągi formatujące liczbę, które zawierają zestaw symboli, które można łączyć w celu zdefiniowania niestandardowych specyfikatorów formatu liczbowego.Custom numeric format strings, which provide a set of symbols that can be combined to define custom numeric format specifiers. Mogą być również używane z dowolną metodą formatowania liczbowego, taką jak Decimal.ToString(String), która ma parametr format.They can also be used with any numeric formatting method, such as Decimal.ToString(String), that has a format parameter. Aby uzyskać szczegółowe informacje, zobacz Niestandardowe ciągi formatujące.For details, see Custom Numeric Format Strings.

  • Niestandardowe CultureInfo lub obiekty NumberFormatInfo, które definiują symbole i wzorce formatu używane do wyświetlania reprezentacji ciągów wartości liczbowych.Custom CultureInfo or NumberFormatInfo objects, which define the symbols and format patterns used in displaying the string representations of numeric values. Można ich używać z dowolną metodą formatowania liczbowego, taką jak ToString, która ma parametr provider.You can use them with any numeric formatting method, such as ToString, that has a provider parameter. Zazwyczaj parametr provider służy do określania formatowania specyficznego dla kultury.Typically, the provider parameter is used to specify culture-specific formatting.

W niektórych przypadkach (na przykład gdy aplikacja musi wyświetlić sformatowany numer konta, numer identyfikacyjny lub kod pocztowy) te trzy techniki są nieodpowiednie.In some cases (such as when an application must display a formatted account number, an identification number, or a postal code) these three techniques are inappropriate. .NET Framework umożliwia również zdefiniowanie obiektu formatowania, który nie jest CultureInfo ani obiektem NumberFormatInfo, aby określić sposób formatowania wartości liczbowej.The .NET Framework also enables you to define a formatting object that is neither a CultureInfo nor a NumberFormatInfo object to determine how a numeric value is formatted. Ten temat zawiera instrukcje krok po kroku dotyczące implementowania takiego obiektu i zawiera przykład formatowania numerów telefonów.This topic provides the step-by-step instructions for implementing such an object, and provides an example that formats telephone numbers.

Aby zdefiniować niestandardowego dostawcę formatowaniaTo define a custom format provider

  1. Zdefiniuj klasę implementującą interfejsy IFormatProvider i ICustomFormatter.Define a class that implements the IFormatProvider and ICustomFormatter interfaces.

  2. Zaimplementuj metodę IFormatProvider.GetFormat.Implement the IFormatProvider.GetFormat method. GetFormat to metoda wywołania zwrotnego, która Metoda formatowania (taka jak Metoda String.Format(IFormatProvider, String, Object[])) wywołuje, aby pobrać obiekt, który jest odpowiedzialny za wykonywanie formatowania niestandardowego.GetFormat is a callback method that the formatting method (such as the String.Format(IFormatProvider, String, Object[]) method) invokes to retrieve the object that is actually responsible for performing custom formatting. Typowa implementacja GetFormat wykonuje następujące czynności:A typical implementation of GetFormat does the following:

    1. Określa, czy obiekt Type przekazywać jako parametr metody reprezentuje interfejs ICustomFormatter.Determines whether the Type object passed as a method parameter represents an ICustomFormatter interface.

    2. Jeśli parametr reprezentuje interfejs ICustomFormatter, GetFormat zwraca obiekt implementujący interfejs ICustomFormatter, który jest odpowiedzialny za dostarczanie formatowania niestandardowego.If the parameter does represent the ICustomFormatter interface, GetFormat returns an object that implements the ICustomFormatter interface that is responsible for providing custom formatting. Zazwyczaj obiekt formatowania niestandardowego zwraca sam siebie.Typically, the custom formatting object returns itself.

    3. Jeśli parametr nie reprezentuje interfejsu ICustomFormatter, GetFormat zwraca null.If the parameter does not represent the ICustomFormatter interface, GetFormat returns null.

  3. Zaimplementuj metodę Format.Implement the Format method. Ta metoda jest wywoływana przez metodę String.Format(IFormatProvider, String, Object[]) i jest odpowiedzialna za zwracanie ciągu reprezentującego liczbę.This method is called by the String.Format(IFormatProvider, String, Object[]) method and is responsible for returning the string representation of a number. Implementacja metody zwykle obejmuje następujące elementy:Implementing the method typically involves the following:

    1. Opcjonalnie upewnij się, że metoda jest uzasadniona w celu zapewnienia usług formatowania, badając parametr provider.Optionally, make sure that the method is legitimately intended to provide formatting services by examining the provider parameter. W przypadku formatowania obiektów, które implementują zarówno IFormatProvider, jak i ICustomFormatter, obejmuje to testowanie parametru provider dla równości z bieżącym obiektem formatowania.For formatting objects that implement both IFormatProvider and ICustomFormatter, this involves testing the provider parameter for equality with the current formatting object.

    2. Ustal, czy obiekt formatowania powinien obsługiwać niestandardowe specyfikatory formatu.Determine whether the formatting object should support custom format specifiers. (Na przykład specyfikator formatu "N" może wskazywać, że numer telefonu w Stanach Zjednoczonych powinien być wyjściowy w formacie NANP, a "I" może wskazywać na dane wyjściowe w formacie E. 123 z zaleceniem ITU-T). Jeśli używane są specyfikatory formatu, metoda powinna obsługiwać określony specyfikator formatu.(For example, an "N" format specifier might indicate that a U.S. telephone number should be output in NANP format, and an "I" might indicate output in ITU-T Recommendation E.123 format.) If format specifiers are used, the method should handle the specific format specifier. Jest ona przenoszona do metody w parametrze format.It is passed to the method in the format parameter. Jeśli żaden specyfikator nie jest obecny, wartość parametru format jest String.Empty.If no specifier is present, the value of the format parameter is String.Empty.

    3. Pobierz wartość liczbową przekazaną do metody jako parametr arg.Retrieve the numeric value passed to the method as the arg parameter. Wykonaj wszelkie manipulacje wymagane do przekonwertowania go na jego reprezentację ciągu.Perform whatever manipulations are required to convert it to its string representation.

    4. Zwraca ciąg reprezentujący parametr arg.Return the string representation of the arg parameter.

Aby użyć niestandardowego obiektu formatowania liczbowegoTo use a custom numeric formatting object

  1. Utwórz nowe wystąpienie niestandardowej klasy formatowania.Create a new instance of the custom formatting class.

  2. Wywołaj metodę formatowania String.Format(IFormatProvider, String, Object[]), przekazując ją do niestandardowego obiektu formatowania, specyfikator formatowania (lub String.Empty, jeśli nie jest używany) i wartość liczbową do sformatowania.Call the String.Format(IFormatProvider, String, Object[]) formatting method, passing it the custom formatting object, the formatting specifier (or String.Empty, if one is not used), and the numeric value to be formatted.

PrzykładExample

W poniższym przykładzie zdefiniowano niestandardowego dostawcę formatu liczbowego o nazwie TelephoneFormatter, który konwertuje liczbę reprezentującą numer telefonu w Stanach Zjednoczonych do formatu NANP lub E. 123.The following example defines a custom numeric format provider named TelephoneFormatter that converts a number that represents a U.S. telephone number to its NANP or E.123 format. Metoda obsługuje dwa specyfikatory formatu: "N" (który wyprowadza format NANP) i "I" (który wyprowadza międzynarodowy format E. 123).The method handles two format specifiers, "N" (which outputs the NANP format) and "I" (which outputs the international E.123 format).

using System;
using System.Globalization;

public class TelephoneFormatter : IFormatProvider, ICustomFormatter
{
   public object GetFormat(Type formatType)
   {
      if (formatType == typeof(ICustomFormatter))
         return this;
      else
         return null;
   }               

   public string Format(string format, object arg, IFormatProvider formatProvider)
   {
      // Check whether this is an appropriate callback             
      if (! this.Equals(formatProvider))
         return null; 

      // Set default format specifier             
      if (string.IsNullOrEmpty(format)) 
         format = "N";

      string numericString = arg.ToString();
      
      if (format == "N")
      {
         if (numericString.Length <= 4)
            return numericString;
         else if (numericString.Length == 7)
            return numericString.Substring(0, 3) + "-" + numericString.Substring(3, 4); 
         else if (numericString.Length == 10)
               return "(" + numericString.Substring(0, 3) + ") " +
                      numericString.Substring(3, 3) + "-" + numericString.Substring(6);   
         else
            throw new FormatException( 
                      string.Format("'{0}' cannot be used to format {1}.", 
                                    format, arg.ToString()));
      }
      else if (format == "I")
      {
         if (numericString.Length < 10)
            throw new FormatException(string.Format("{0} does not have 10 digits.", arg.ToString()));
         else
            numericString = "+1 " + numericString.Substring(0, 3) + " " + numericString.Substring(3, 3) + " " + numericString.Substring(6);
      }
      else
      {
         throw new FormatException(string.Format("The {0} format specifier is invalid.", format));
      } 
      return numericString;  
   }
}

public class TestTelephoneFormatter
{
   public static void Main()
   {
      Console.WriteLine(String.Format(new TelephoneFormatter(), "{0}", 0));
      Console.WriteLine(String.Format(new TelephoneFormatter(), "{0}", 911));
      Console.WriteLine(String.Format(new TelephoneFormatter(), "{0}", 8490216));
      Console.WriteLine(String.Format(new TelephoneFormatter(), "{0}", 4257884748));
      
      Console.WriteLine(String.Format(new TelephoneFormatter(), "{0:N}", 0));
      Console.WriteLine(String.Format(new TelephoneFormatter(), "{0:N}", 911));
      Console.WriteLine(String.Format(new TelephoneFormatter(), "{0:N}", 8490216));
      Console.WriteLine(String.Format(new TelephoneFormatter(), "{0:N}", 4257884748));

      Console.WriteLine(String.Format(new TelephoneFormatter(), "{0:I}", 4257884748));
   }
}
Public Class TelephoneFormatter : Implements IFormatProvider, ICustomFormatter
   Public Function GetFormat(formatType As Type) As Object _
                   Implements IFormatProvider.GetFormat
      If formatType Is GetType(ICustomFormatter) Then
         Return Me
      Else
         Return Nothing
      End If               
   End Function               

   Public Function Format(fmt As String, arg As Object, _
                          formatProvider As IFormatProvider) As String _
                   Implements ICustomFormatter.Format
      ' Check whether this is an appropriate callback             
      If Not Me.Equals(formatProvider) Then Return Nothing 

      ' Set default format specifier             
      If String.IsNullOrEmpty(fmt) Then fmt = "N"

      Dim numericString As String = arg.ToString
      
      If fmt = "N" Then
         Select Case numericString.Length
            Case <= 4 
               Return numericString
            Case 7
               Return Left(numericString, 3) & "-" & Mid(numericString, 4) 
            Case 10
               Return "(" & Left(numericString, 3) & ") " & _
                      Mid(numericString, 4, 3) & "-" & Mid(numericString, 7)   
            Case Else
               Throw New FormatException( _
                         String.Format("'{0}' cannot be used to format {1}.", _
                                       fmt, arg.ToString()))
         End Select
      ElseIf fmt = "I" Then
         If numericString.Length < 10 Then
            Throw New FormatException(String.Format("{0} does not have 10 digits.", arg.ToString()))
         Else
            numericString = "+1 " & Left(numericString, 3) & " " & Mid(numericString, 4, 3) & " " & Mid(numericString, 7)
         End If      
      Else
         Throw New FormatException(String.Format("The {0} format specifier is invalid.", fmt))
      End If 
      Return numericString  
   End Function
End Class

Public Module TestTelephoneFormatter
   Public Sub Main
      Console.WriteLine(String.Format(New TelephoneFormatter, "{0}", 0))
      Console.WriteLine(String.Format(New TelephoneFormatter, "{0}", 911))
      Console.WriteLine(String.Format(New TelephoneFormatter, "{0}", 8490216))
      Console.WriteLine(String.Format(New TelephoneFormatter, "{0}", 4257884748))
      
      Console.WriteLine(String.Format(New TelephoneFormatter, "{0:N}", 0))
      Console.WriteLine(String.Format(New TelephoneFormatter, "{0:N}", 911))
      Console.WriteLine(String.Format(New TelephoneFormatter, "{0:N}", 8490216))
      Console.WriteLine(String.Format(New TelephoneFormatter, "{0:N}", 4257884748))

      Console.WriteLine(String.Format(New TelephoneFormatter, "{0:I}", 4257884748))
   End Sub
End Module

Niestandardowego dostawcy formatu liczbowego można używać tylko z metodą String.Format(IFormatProvider, String, Object[]).The custom numeric format provider can be used only with the String.Format(IFormatProvider, String, Object[]) method. Inne przeciążenia metod formatowania liczbowego (takich jak ToString), które mają parametr typu IFormatProvider wszystkie, przekażą IFormatProvider.GetFormat implementację Type obiektu, który reprezentuje typ NumberFormatInfo.The other overloads of numeric formatting methods (such as ToString) that have a parameter of type IFormatProvider all pass the IFormatProvider.GetFormat implementation a Type object that represents the NumberFormatInfo type. W elemencie Return oczekujemy, że metoda zwróci obiekt NumberFormatInfo.In return, they expect the method to return a NumberFormatInfo object. Jeśli tak nie jest, dostawca niestandardowego formatu liczbowego jest ignorowany, a w jego miejsce jest używany obiekt NumberFormatInfo dla bieżącej kultury.If it does not, the custom numeric format provider is ignored, and the NumberFormatInfo object for the current culture is used in its place. W przykładzie metoda TelephoneFormatter.GetFormat obsługuje możliwość, że może być niewłaściwie przenoszona do metody formatowania liczbowego poprzez zbadanie parametru Method i zwrócenie null, jeśli reprezentuje typ inny niż ICustomFormatter.In the example, the TelephoneFormatter.GetFormat method handles the possibility that it may be inappropriately passed to a numeric formatting method by examining the method parameter and returning null if it represents a type other than ICustomFormatter.

Jeśli dostawca niestandardowego formatu liczb obsługuje zestaw specyfikatorów formatu, upewnij się, że zostało podane zachowanie domyślne, jeśli w elemencie formatu użytym w wywołaniu metody String.Format(IFormatProvider, String, Object[]) nie podano specyfikatora formatu.If a custom numeric format provider supports a set of format specifiers, make sure you provide a default behavior if no format specifier is supplied in the format item used in the String.Format(IFormatProvider, String, Object[]) method call. W przykładzie "N" jest domyślnym specyfikatorem formatu.In the example, "N" is the default format specifier. Pozwala to na konwersję liczby na sformatowany numer telefonu przez udostępnienie jawnego specyfikatora formatu.This allows for a number to be converted to a formatted telephone number by providing an explicit format specifier. Poniższy przykład ilustruje takie wywołanie metody.The following example illustrates such a method call.

Console.WriteLine(String.Format(new TelephoneFormatter(), "{0:N}", 4257884748));
Console.WriteLine(String.Format(New TelephoneFormatter, "{0:N}", 4257884748))

Jednak umożliwia również konwersję, jeśli nie ma specyfikatora formatu.But it also allows the conversion to occur if no format specifier is present. Poniższy przykład ilustruje takie wywołanie metody.The following example illustrates such a method call.

Console.WriteLine(String.Format(new TelephoneFormatter(), "{0}", 4257884748));
Console.WriteLine(String.Format(New TelephoneFormatter, "{0}", 4257884748))

Jeśli nie zdefiniowano żadnego domyślnego specyfikatora formatu, implementacja metody ICustomFormatter.Format powinna obejmować kod, taki jak poniższy, aby program .NET mógł zapewnić formatowanie, którego kod nie obsługuje.If no default format specifier is defined, your implementation of the ICustomFormatter.Format method should include code such as the following so that .NET can provide formatting that your code does not support.

if (arg is IFormattable) 
   s = ((IFormattable)arg).ToString(format, formatProvider);
else if (arg != null)    
   s = arg.ToString();
If TypeOf(arg) Is IFormattable Then 
   s = DirectCast(arg, IFormattable).ToString(fmt, formatProvider)
ElseIf arg IsNot Nothing Then    
   s = arg.ToString()
End If

W przypadku tego przykładu Metoda implementująca ICustomFormatter.Format ma służyć jako metoda wywołania zwrotnego dla metody String.Format(IFormatProvider, String, Object[]).In the case of this example, the method that implements ICustomFormatter.Format is intended to serve as a callback method for the String.Format(IFormatProvider, String, Object[]) method. W związku z tym sprawdza parametr formatProvider, aby określić, czy zawiera odwołanie do bieżącego obiektu TelephoneFormatter.Therefore, it examines the formatProvider parameter to determine whether it contains a reference to the current TelephoneFormatter object. Jednak metodę można również wywołać bezpośrednio z kodu.However, the method can also be called directly from code. W takim przypadku można użyć parametru formatProvider, aby dostarczyć CultureInfo lub NumberFormatInfo obiekt, który dostarcza informacje o formatowaniu specyficzne dla kultury.In that case, you can use the formatProvider parameter to provide a CultureInfo or NumberFormatInfo object that supplies culture-specific formatting information.

Zobacz takżeSee also