Comment : définir et utiliser des fournisseurs de format numérique personnalisésHow to: Define and Use Custom Numeric Format Providers

Le .NET Framework vous donne un contrôle étendu sur la représentation sous forme de chaîne de valeurs numériques.The .NET Framework gives you extensive control over the string representation of numeric values. Il prend en charge les fonctionnalités suivantes pour personnaliser le format des valeurs numériques :It supports the following features for customizing the format of numeric values:

  • Chaînes de format numériques standard, qui fournissent un ensemble prédéfini de formats pour convertir des nombres dans leur représentation sous forme de chaîne.Standard numeric format strings, which provide a predefined set of formats for converting numbers to their string representation. Vous pouvez les utiliser avec toute méthode de mise en forme numérique, telle que Decimal.ToString(String), qui est dotée d’un paramètre format.You can use them with any numeric formatting method, such as Decimal.ToString(String), that has a format parameter. Pour plus d’informations, consultez Chaînes de format numériques standard.For details, see Standard Numeric Format Strings.

  • Chaînes de format numériques personnalisées, qui fournissent un ensemble de symboles pouvant être combinés pour définir des spécificateurs de format numériques personnalisés.Custom numeric format strings, which provide a set of symbols that can be combined to define custom numeric format specifiers. Elles peuvent également être utilisées avec toute méthode de mise en forme numérique, telle que Decimal.ToString(String), qui est dotée d’un paramètre format.They can also be used with any numeric formatting method, such as Decimal.ToString(String), that has a format parameter. Pour plus d’informations, consultez Chaînes de format numériques personnalisées.For details, see Custom Numeric Format Strings.

  • Personnalisez les objets CultureInfo ou NumberFormatInfo, qui définissent les symboles et les modèles de format utilisés pour afficher les représentations sous forme de chaîne des valeurs numériques.Custom CultureInfo or NumberFormatInfo objects, which define the symbols and format patterns used in displaying the string representations of numeric values. Vous pouvez les utiliser avec toute méthode de mise en forme numérique, telle que ToString, qui est dotée d’un paramètre provider.You can use them with any numeric formatting method, such as ToString, that has a provider parameter. En règle générale, le paramètre provider est utilisé pour spécifier une mise en forme propre à la culture.Typically, the provider parameter is used to specify culture-specific formatting.

Dans certains cas (par exemple, quand une application doit afficher un numéro de compte mis en forme, un numéro d’identification ou un code postal), ces trois techniques sont inappropriées.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. Le .NET Framework vous permet également de définir un objet de mise en forme qui n’est ni un objet CultureInfo ni un objet NumberFormatInfo pour déterminer la mise en forme d’une valeur numérique.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. Cette rubrique fournit des instructions détaillées pour l’implémentation de ce type d’objet et fournit un exemple qui met en forme les numéros de téléphone.This topic provides the step-by-step instructions for implementing such an object, and provides an example that formats telephone numbers.

Pour définir un fournisseur de format personnaliséTo define a custom format provider

  1. Définir une classe qui implémente les inferfaces IFormatProvider et ICustomFormatter.Define a class that implements the IFormatProvider and ICustomFormatter interfaces.

  2. Implémentez la méthode IFormatProvider.GetFormat.Implement the IFormatProvider.GetFormat method. GetFormat est une méthode de rappel que la méthode de mise en forme (telle que la méthode String.Format(IFormatProvider, String, Object[])) appelle pour récupérer l’objet qui est réellement chargé d’effectuer la mise en forme personnalisée.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. Une implémentation type de GetFormat effectue les opérations suivantes :A typical implementation of GetFormat does the following:

    1. Elle détermine si l’objet Type passé comme paramètre de méthode représente une interface ICustomFormatter.Determines whether the Type object passed as a method parameter represents an ICustomFormatter interface.

    2. Si le paramètre représente l’interface ICustomFormatter, GetFormat retourne un objet qui implémente l’interface ICustomFormatter chargée de fournir la mise en forme personnalisée.If the parameter does represent the ICustomFormatter interface, GetFormat returns an object that implements the ICustomFormatter interface that is responsible for providing custom formatting. En général, l’objet de mise en forme personnalisée retourne lui-même.Typically, the custom formatting object returns itself.

    3. Si le paramètre ne représente pas l’interface ICustomFormatter, GetFormat retourne null.If the parameter does not represent the ICustomFormatter interface, GetFormat returns null.

  3. Implémentez la méthode Format.Implement the Format method. Cette méthode est appelée par la méthode String.Format(IFormatProvider, String, Object[]) et est chargée de retourner la représentation sous forme de chaîne d’un nombre.This method is called by the String.Format(IFormatProvider, String, Object[]) method and is responsible for returning the string representation of a number. En général, l’implémentation de la méthode implique les étapes suivantes :Implementing the method typically involves the following:

    1. Le cas échéant, vérifiez que la méthode est légitimement destinée à fournir des services de mise en forme en examinant le paramètre provider.Optionally, make sure that the method is legitimately intended to provide formatting services by examining the provider parameter. Pour les objets de mise en forme qui implémentent à la fois IFormatProvider et ICustomFormatter, vous devez déterminer si le paramètre provider correspond à l’objet de mise en forme actuel.For formatting objects that implement both IFormatProvider and ICustomFormatter, this involves testing the provider parameter for equality with the current formatting object.

    2. Déterminez si l’objet de mise en forme doit prendre en charge les spécificateurs de format personnalisés.Determine whether the formatting object should support custom format specifiers. (Par exemple, un spécificateur de format « N » peut indiquer qu’un numéro de téléphone américain doit être généré au format NANP, et un « I » peut indiquer une sortie au format E. 123 de la recommandation ITU-T.) Si les spécificateurs de format sont utilisés, la méthode doit gérer le spécificateur de format spécifique.(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. Ill est passé à la méthode dans le paramètre format.It is passed to the method in the format parameter. Si aucun spécificateur n’est présent, la valeur du paramètre format est String.Empty.If no specifier is present, the value of the format parameter is String.Empty.

    3. Récupérez la valeur numérique passée à la méthode comme paramètre arg.Retrieve the numeric value passed to the method as the arg parameter. Effectuez toute opération requise pour le convertir en sa représentation sous forme de chaîne.Perform whatever manipulations are required to convert it to its string representation.

    4. Retournez la représentation sous forme de chaîne du paramètre arg.Return the string representation of the arg parameter.

Pour utiliser un objet de mise en forme numérique personnaliséTo use a custom numeric formatting object

  1. Créez une instance de la classe de mise en forme personnalisée.Create a new instance of the custom formatting class.

  2. Appelez la méthode de mise en forme String.Format(IFormatProvider, String, Object[]) en lui passant l’objet de mise en forme personnalisée, le spécificateur de mise en forme (ou String.Empty, si aucun n’est utilisé) et la valeur numérique à mettre en forme.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.

ExempleExample

L’exemple suivant définit un fournisseur de format numérique personnalisé nommé TelephoneFormatter qui convertit un nombre représentant un numéro de téléphone aux États-Unis au format NANP ou E.123 correspondant.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. La méthode gère deux spécificateurs de format, « N » (qui génère le format NANP) et « I » (qui génère le format E.123 international).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

Le fournisseur de format numérique personnalisé peut être utilisé uniquement avec la méthode String.Format(IFormatProvider, String, Object[]).The custom numeric format provider can be used only with the String.Format(IFormatProvider, String, Object[]) method. Les autres surcharges des méthodes de mise en forme numérique (telles que ToString) dotées d’un paramètre de type IFormatProvider passent toutes à l’implémentation IFormatProvider.GetFormat un objet Type qui représente le type 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. La méthode doit normalement leur retourner un objet NumberFormatInfo.In return, they expect the method to return a NumberFormatInfo object. Si elle ne le fait pas, le fournisseur de format numérique personnalisé est ignoré et l’objet NumberFormatInfo pour la culture actuelle est utilisé à la place.If it does not, the custom numeric format provider is ignored, and the NumberFormatInfo object for the current culture is used in its place. Dans l’exemple, la méthode TelephoneFormatter.GetFormat vérifie si la transmission à une méthode de mise en forme numérique est effectuée de façon inappropriée ; elle examine le paramètre de méthode et retourne une valeur null si le type représenté n’est pas 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.

Si un fournisseur de format numérique personnalisé prend en charge un jeu de spécificateurs de format, vérifiez que vous fournissez un comportement par défaut si aucun spécificateur de format n’est fourni dans l’élément de format utilisé dans l’appel de la méthode String.Format(IFormatProvider, String, Object[]).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. Dans l’exemple, « N » est le spécificateur de format par défaut.In the example, "N" is the default format specifier. Cela permet de convertir un nombre en un numéro de téléphone mis en forme en fournissant un spécificateur de format explicite.This allows for a number to be converted to a formatted telephone number by providing an explicit format specifier. L’exemple suivant illustre un appel de méthode de ce type.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))

Mais il permet également la conversion si aucun spécificateur de format n’est présent.But it also allows the conversion to occur if no format specifier is present. L’exemple suivant illustre un appel de méthode de ce type.The following example illustrates such a method call.

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

Si aucun spécificateur de format par défaut n’est défini, votre implémentation de la méthode ICustomFormatter.Format doit inclure le code suivant afin que .NET puisse fournir la mise en forme que votre code ne prend pas en charge.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

Dans le cas de cet exemple, la méthode qui implémente ICustomFormatter.Format est destinée à servir de méthode de rappel pour la méthode 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. Ainsi, elle examine le paramètre formatProvider pour déterminer s’il contient une référence à l’objet TelephoneFormatter actuel.Therefore, it examines the formatProvider parameter to determine whether it contains a reference to the current TelephoneFormatter object. Toutefois, la méthode peut également être appelée directement à partir du code.However, the method can also be called directly from code. Dans ce cas, vous pouvez utiliser le paramètre formatProvider pour fournir un objet CultureInfo ou NumberFormatInfo qui fournit des informations de mise en forme spécifiques à la culture.In that case, you can use the formatProvider parameter to provide a CultureInfo or NumberFormatInfo object that supplies culture-specific formatting information.

Voir aussiSee also