Vorgehensweise: Definieren und Verwenden von benutzerdefinierten numerischen FormatanbieternHow to: Define and Use Custom Numeric Format Providers

.NET Framework ermöglicht eine umfangreiche Steuerung der Zeichenfolgendarstellung numerischer Werte.The .NET Framework gives you extensive control over the string representation of numeric values. Die folgenden Funktionen für die Anpassung des Formats numerischer Werte werden unterstützt:It supports the following features for customizing the format of numeric values:

  • Standardmäßige Zahlenformatzeichenfolgen, die einen vordefinierten Satz an Formaten für die Konvertierung von Zahlen in ihre Zeichenfolgendarstellung bereitstellen.Standard numeric format strings, which provide a predefined set of formats for converting numbers to their string representation. Sie können diese mit jeder Zahlenformatierungsmethode verwenden, die über einen format-Parameter verfügt, z.B. Decimal.ToString(String).You can use them with any numeric formatting method, such as Decimal.ToString(String), that has a format parameter. Weitere Informationen finden Sie unter Standardmäßige Zahlenformatzeichenfolgen.For details, see Standard Numeric Format Strings.

  • Benutzerdefinierte Zahlenformatzeichenfolgen, die einen Satz von Symbolen bereitstellen, die kombiniert werden können, um benutzerdefinierte Zahlenformatbezeichner zu definieren.Custom numeric format strings, which provide a set of symbols that can be combined to define custom numeric format specifiers. Sie können auch mit jeder Zahlenformatierungsmethode verwendet werden, die über einen format-Parameter verfügt, z.B. Decimal.ToString(String).They can also be used with any numeric formatting method, such as Decimal.ToString(String), that has a format parameter. Weitere Informationen finden Sie unter Benutzerdefinierte Zahlenformatzeichenfolgen.For details, see Custom Numeric Format Strings.

  • Benutzerdefinierte CultureInfo- oder NumberFormatInfo-Objekte, die die beim Anzeigen der Zeichenfolgendarstellungen numerischer Werte verwendeten Symbole und Formatmuster definieren.Custom CultureInfo or NumberFormatInfo objects, which define the symbols and format patterns used in displaying the string representations of numeric values. Sie können diese mit jeder Zahlenformatierungsmethode verwenden, die über einen provider-Parameter verfügt, z.B. ToString.You can use them with any numeric formatting method, such as ToString, that has a provider parameter. Üblicherweise wird der provider-Parameter verwendet, um eine kulturspezifische Formatierung anzugeben.Typically, the provider parameter is used to specify culture-specific formatting.

In einigen Fällen (z.B. wenn eine Anwendung eine formatierte Kontonummer, eine ID oder eine Postleitzahl anzeigen muss) sind diese drei Techniken nicht geeignet.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 ermöglicht Ihnen auch die Definition eines Formatierungsobjekts, bei dem es sich weder um ein CultureInfo-Objekt noch um ein NumberFormatInfo-Objekt handelt, um zu bestimmen, wie ein numerischer Wert formatiert wird.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. Dieses Thema stellt eine Schrittanleitung für die Implementierung eines solchen Objekts bereit und bietet ein Beispiel, das Telefonnummern formatiert.This topic provides the step-by-step instructions for implementing such an object, and provides an example that formats telephone numbers.

Definieren eines benutzerdefinierten FormatanbietersTo define a custom format provider

  1. Definieren Sie eine Klasse, die die IFormatProvider- und ICustomFormatter-Schnittstelle implementiert.Define a class that implements the IFormatProvider and ICustomFormatter interfaces.

  2. Implementieren Sie die IFormatProvider.GetFormat-Methode.Implement the IFormatProvider.GetFormat method. GetFormat ist eine Rückrufmethode, die von der Formatierungsmethode (z.B. der String.Format(IFormatProvider, String, Object[])-Methode) aufgerufen wird, um das Objekt abzurufen, das tatsächlich für die benutzerdefinierte Formatierung zuständig ist.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. Eine typische Implementierung von GetFormat führt Folgendes aus:A typical implementation of GetFormat does the following:

    1. Bestimmt, ob das als Methodenparameter übergebene Type-Objekt eine ICustomFormatter-Schnittstelle darstellt.Determines whether the Type object passed as a method parameter represents an ICustomFormatter interface.

    2. Wenn der Parameter die ICustomFormatter-Schnittstelle tatsächlich darstellt, gibt GetFormat ein Objekt zurück, das die für die benutzerdefinierte Formatierung zuständige ICustomFormatter-Schnittstelle implementiert.If the parameter does represent the ICustomFormatter interface, GetFormat returns an object that implements the ICustomFormatter interface that is responsible for providing custom formatting. Üblicherweise gibt das benutzerdefinierte Formatierungsobjekt sich selbst zurück.Typically, the custom formatting object returns itself.

    3. Wenn der Parameter die ICustomFormatter-Schnittstelle nicht darstellt, gibt GetFormat null zurück.If the parameter does not represent the ICustomFormatter interface, GetFormat returns null.

  3. Implementieren Sie die Format-Methode.Implement the Format method. Diese Methode wird von der String.Format(IFormatProvider, String, Object[])-Methode aufgerufen und ist für die Rückgabe der Zeichenfolgendarstellung einer Zahl zuständig.This method is called by the String.Format(IFormatProvider, String, Object[]) method and is responsible for returning the string representation of a number. Die Implementierung der Methode umfasst üblicherweise Folgendes:Implementing the method typically involves the following:

    1. Stellen Sie optional sicher, dass die Methode dazu in der Lage sein soll, Formatierungsdienste bereitzustellen, indem Sie den provider-Parameter untersuchen.Optionally, make sure that the method is legitimately intended to provide formatting services by examining the provider parameter. Bei Formatierungsobjekten, die sowohl IFormatProvider als auch ICustomFormatter implementieren, umfasst dies das Testen des provider-Parameters auf Gleichheit mit dem aktuellen Formatierungsobjekt.For formatting objects that implement both IFormatProvider and ICustomFormatter, this involves testing the provider parameter for equality with the current formatting object.

    2. Bestimmen Sie, ob das Formatierungsobjekt benutzerdefinierte Formatbezeichner unterstützen soll.Determine whether the formatting object should support custom format specifiers. (Beispielsweise könnte ein Formatbezeichner „N“ angeben, dass eine US-amerikanische Telefonnummer im NANP-Format (Nordamerikanischer Nummerierungsplan) ausgegeben werden soll, und ein Bezeichner „I“ könnte eine Ausgabe im Format der ITU-T-Empfehlung E.123 angeben.) Wenn Formatbezeichner verwendet werden, muss die Methode den angegebenen Formatbezeichner verarbeiten.(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. Der Bezeichner wird im format-Parameter der Methode übergeben.It is passed to the method in the format parameter. Wenn kein Bezeichner vorhanden ist, lautet der Wert des format-Parameters String.Empty.If no specifier is present, the value of the format parameter is String.Empty.

    3. Rufen Sie den numerischen Wert ab, der als arg-Parameter der Methode übergeben wurde.Retrieve the numeric value passed to the method as the arg parameter. Führen Sie alle Änderungen durch, die notwendig sind, um den Wert in seine Zeichenfolgendarstellung zu konvertieren.Perform whatever manipulations are required to convert it to its string representation.

    4. Geben Sie die Zeichenfolgendarstellung des arg-Parameters zurück.Return the string representation of the arg parameter.

Verwenden eines benutzerdefinierten ZahlenformatierungsobjektsTo use a custom numeric formatting object

  1. Erstellen Sie eine neue Instanz der benutzerdefinierten Formatierungsklasse.Create a new instance of the custom formatting class.

  2. Rufen Sie die String.Format(IFormatProvider, String, Object[])-Formatierungsmethode auf, und übergeben Sie das benutzerdefinierte Formatierungsobjekt, den Formatierungsbezeichner (oder String.Empty, falls kein Bezeichner verwendet wird) und den numerischen Wert, der formatiert werden soll.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.

BeispielExample

Das folgende Beispiel definiert einen benutzerdefinierten Zahlenformatanbieter namens TelephoneFormatter, der eine Zahl, die eine US-amerikanische Telefonnummer darstellt, in das entsprechende NANP- oder E.123-Format konvertiert.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. Die Methode verarbeitet zwei Formatbezeichner: „N“ (zur Ausgabe des NANP-Formats) und „I“ (zur Ausgabe des internationalen E.123-Formats).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

Der benutzerdefinierte Zahlenformatanbieter kann nur mit der String.Format(IFormatProvider, String, Object[])-Methode verwendet werden.The custom numeric format provider can be used only with the String.Format(IFormatProvider, String, Object[]) method. Alle anderen Überladungen der Zahlenformatierungsmethoden (z.B. ToString), die einen Parameter des Typs IFormatProvider aufweisen, übergeben der IFormatProvider.GetFormat-Implementierung ein Type-Objekt, das den NumberFormatInfo-Typ darstellt.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. Im Gegenzug erwarten sie, dass die Methode ein NumberFormatInfo-Objekt zurückgibt.In return, they expect the method to return a NumberFormatInfo object. Wenn dies nicht der Fall ist, wird der benutzerdefinierte Zahlenformatanbieter ignoriert und stattdessen das NumberFormatInfo-Objekt für die aktuelle Kultur verwendet.If it does not, the custom numeric format provider is ignored, and the NumberFormatInfo object for the current culture is used in its place. Im Beispiel verarbeitet die TelephoneFormatter.GetFormat-Methode die Möglichkeit, dass sie fälschlicherweise an eine Zahlenformatierungsmethode übergeben wurde, indem sie den Methodenparameter untersucht und null zurückgibt, wenn dieser einen anderen Typ als ICustomFormatter darstellt.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.

Wenn ein benutzerdefinierter Zahlenformatanbieter einen Satz von Formatbezeichnern unterstützt, stellen Sie sicher, dass Sie ein Standardverhalten einrichten, falls in dem Formatelement, das im String.Format(IFormatProvider, String, Object[])-Methodenaufruf verwendet wird, kein Formatbezeichner bereitgestellt wird.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. Im Beispiel ist „N“ der Standardformatbezeichner.In the example, "N" is the default format specifier. Dadurch kann eine Zahl in eine formatierte Telefonnummer konvertiert werden, indem ein expliziter Formatbezeichner bereitgestellt wird.This allows for a number to be converted to a formatted telephone number by providing an explicit format specifier. Das folgende Beispiel veranschaulicht einen solchen Methodenaufruf.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))

Es ermöglicht die Konvertierung aber auch, falls kein Formatbezeichner vorhanden ist.But it also allows the conversion to occur if no format specifier is present. Das folgende Beispiel veranschaulicht einen solchen Methodenaufruf.The following example illustrates such a method call.

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

Wenn kein Standardformatbezeichner definiert ist, muss Ihre Implementierung der ICustomFormatter.Format-Methode einen Code wie den folgenden beinhalten, damit .NET eine Formatierung bereitstellen kann, die von Ihrem Code nicht unterstützt wird.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

In diesem Beispiel dient die Methode, die ICustomFormatter.Format implementiert, als eine Rückrufmethode der String.Format(IFormatProvider, String, Object[])-Methode.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. Daher untersucht diese Methode den formatProvider-Parameter, um zu ermitteln, ob dieser einen Verweis auf das aktuelle TelephoneFormatter-Objekt enthält.Therefore, it examines the formatProvider parameter to determine whether it contains a reference to the current TelephoneFormatter object. Die Methode kann jedoch auch direkt aus dem Code aufgerufen werden.However, the method can also be called directly from code. In diesem Fall können Sie den formatProvider-Parameter verwenden, um ein CultureInfo- oder NumberFormatInfo-Objekt bereitzustellen, das kulturspezifische Formatierungsinformationen bereitstellt.In that case, you can use the formatProvider parameter to provide a CultureInfo or NumberFormatInfo object that supplies culture-specific formatting information.

Siehe auchSee also