Procedura: definire e utilizzare provider di formati numerici personalizzatiHow to: Define and Use Custom Numeric Format Providers

.NET Framework.NET Frameworkoffre ampio controllo sulla rappresentazione di stringa dei valori numerici.The .NET Framework.NET Framework gives you extensive control over the string representation of numeric values. e supporta le funzionalità seguenti per la personalizzazione del formato di tali valori:It supports the following features for customizing the format of numeric values:

  • Stringhe in formato numerico standard, che forniscono un insieme predefinito di formati per la conversione dei numeri nella rispettiva rappresentazione di stringa.Standard numeric format strings, which provide a predefined set of formats for converting numbers to their string representation. È possibile usarle con qualsiasi metodo di formattazione numerica, ad esempio Decimal.ToString(String), che include un parametro format.You can use them with any numeric formatting method, such as Decimal.ToString(String), that has a format parameter. Per informazioni dettagliate, vedere Stringhe di formato numerico standard.For details, see Standard Numeric Format Strings.

  • Stringhe in formato numerico personalizzato che forniscono un insieme di simboli che possono essere combinati per definire identificatori di formato numerico personalizzato.Custom numeric format strings, which provide a set of symbols that can be combined to define custom numeric format specifiers. È anche possibile usarle con qualsiasi metodo di formattazione numerica, ad esempio Decimal.ToString(String), che include un parametro format.They can also be used with any numeric formatting method, such as Decimal.ToString(String), that has a format parameter. Per informazioni dettagliate, vedere Stringhe in formato numerico personalizzato.For details, see Custom Numeric Format Strings.

  • Oggetti CultureInfo o NumberFormatInfo personalizzati, che definiscono i simboli e i modelli di formato usati per la visualizzazione delle rappresentazioni di stringa di valori numerici.Custom CultureInfo or NumberFormatInfo objects, which define the symbols and format patterns used in displaying the string representations of numeric values. È possibile usarle con qualsiasi metodo di formattazione numerica, ad esempio ToString, che include un parametro provider.You can use them with any numeric formatting method, such as ToString, that has a provider parameter. In genere, il parametro provider viene usato per specificare un formato specifico delle impostazioni cultura.Typically, the provider parameter is used to specify culture-specific formatting.

In alcuni casi, ad esempio quando un'applicazione deve visualizzare un numero di account formattato, un numero di identificazione o un codice postale, queste tre tecniche non sono adatte.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.NET Framework permette anche di definire un oggetto di formattazione diverso da un oggetto CultureInfo o NumberFormatInfo per determinare come viene formattato un valore numerico.The .NET Framework.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. In questo argomento sono contenute istruzioni dettagliate per l'implementazione di tale oggetto ed è anche riportato un esempio di formattazione di numeri di telefono.This topic provides the step-by-step instructions for implementing such an object, and provides an example that formats telephone numbers.

Per definire un provider di formato personalizzatoTo define a custom format provider

  1. Definire una classe che implementa le interfacce IFormatProvider e ICustomFormatter.Define a class that implements the IFormatProvider and ICustomFormatter interfaces.

  2. Implementare il metodo IFormatProvider.GetFormat.Implement the IFormatProvider.GetFormat method. GetFormat è un metodo di callback richiamato dal metodo di formattazione, ad esempio il metodo String.Format(IFormatProvider, String, Object[]), per recuperare l'oggetto effettivamente responsabile della formattazione personalizzata.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. Una tipica implementazione di GetFormat esegue le operazioni seguenti:A typical implementation of GetFormat does the following:

    1. Determina se l'oggetto Type passato come parametro del metodo rappresenta un'interfaccia ICustomFormatter.Determines whether the Type object passed as a method parameter represents an ICustomFormatter interface.

    2. Se il parametro non rappresenta l'interfaccia ICustomFormatter, GetFormat restituisce un oggetto che implementa l'interfaccia ICustomFormatter responsabile della formattazione personalizzata.If the parameter does represent the ICustomFormatter interface, GetFormat returns an object that implements the ICustomFormatter interface that is responsible for providing custom formatting. In genere, l'oggetto di formattazione personalizzata restituisce se stesso.Typically, the custom formatting object returns itself.

    3. Se il parametro non rappresenta l'interfaccia ICustomFormatter, GetFormat restituisce null.If the parameter does not represent the ICustomFormatter interface, GetFormat returns null.

  3. Implementare il metodo Format.Implement the Format method. Questo metodo viene chiamato dal metodo String.Format(IFormatProvider, String, Object[]) ed è responsabile della restituzione della rappresentazione di stringa di un numero.This method is called by the String.Format(IFormatProvider, String, Object[]) method and is responsible for returning the string representation of a number. L'implementazione del metodo in genere implica le attività seguenti:Implementing the method typically involves the following:

    1. Facoltativamente, è possibile verificare che il metodo sia legittimamente responsabile di fornire servizi di formattazione esaminando il parametro provider.Optionally, make sure that the method is legitimately intended to provide formatting services by examining the provider parameter. Per la formattazione di oggetti che implementano sia IFormatProvider sia ICustomFormatter, questa operazione comporta l'esecuzione di test sul parametro provider per verificarne l'uguaglianza all'oggetto di formattazione corrente.For formatting objects that implement both IFormatProvider and ICustomFormatter, this involves testing the provider parameter for equality with the current formatting object.

    2. Stabilire se l'oggetto di formattazione deve supportare identificatori di formato personalizzato.Determine whether the formatting object should support custom format specifiers. Ad esempio, un identificatore di formato "N" potrebbe indicare che un numero di telefono degli Stati Uniti deve essere restituito in formato NANP e un identificatore di formato "I" potrebbe indicare l'output in formato ITU-T Recommendation E.123. Se si usano identificatori di formato, il metodo deve gestire l'identificatore di formato specifico.(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. Quest'ultimo viene passato al metodo nel parametro format.It is passed to the method in the format parameter. Se non è disponibile alcun identificatore, il valore del parametro format è String.Empty.If no specifier is present, the value of the format parameter is String.Empty.

    3. Recuperare il valore numerico passato al metodo come parametro arg.Retrieve the numeric value passed to the method as the arg parameter. Eseguire le eventuali modifiche necessarie per convertirlo nella relativa rappresentazione di stringa.Perform whatever manipulations are required to convert it to its string representation.

    4. Restituire la rappresentazione di stringa del parametro arg.Return the string representation of the arg parameter.

Per usare un oggetto di formattazione numerica personalizzataTo use a custom numeric formatting object

  1. Creare una nuova istanza della classe di formattazione personalizzata.Create a new instance of the custom formatting class.

  2. Chiamare il metodo di formattazione String.Format(IFormatProvider, String, Object[]), passandovi l'oggetto di formattazione personalizzato, l'identificatore di formattazione (o String.Empty se non è specificato alcun identificatore) e il valore numerico da formattare.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.

EsempioExample

Nell'esempio seguente viene definito un provider di formato numerico personalizzato denominato TelephoneFormatter che converte un numero che rappresenta un numero telefonico degli Stati Uniti nel suo formato NANP oppure 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. Il metodo gestisce due identificatori di formato, "N" (che restituisce il formato NANP) e "I" (che restituisce il formato E.123 internazionale).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

Il provider di formati numerici personalizzati può essere usato solo con il metodo String.Format(IFormatProvider, String, Object[]).The custom numeric format provider can be used only with the String.Format(IFormatProvider, String, Object[]) method. Gli altri overload di metodi di formattazione numerica, come ToString, che includono un parametro di tipo IFormatProvider, passano tutti l'implementazione IFormatProvider.GetFormat di un oggetto Type che rappresenta il tipo 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. In cambio, si aspettano che il metodo restituisca un oggetto NumberFormatInfo.In return, they expect the method to return a NumberFormatInfo object. In caso contrario, il provider di formati numerici personalizzati viene ignorato e al suo posto viene usato l'oggetto NumberFormatInfo per le impostazioni cultura correnti.If it does not, the custom numeric format provider is ignored, and the NumberFormatInfo object for the current culture is used in its place. Nell'esempio il metodo TelephoneFormatter.GetFormat gestisce la possibilità di essere passato erroneamente a un metodo di formattazione numerica esaminando il parametro del metodo e restituendo null se rappresenta un tipo diverso da 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.

Se un provider di formati numerici personalizzati supporta un set di identificatori di formato, assicurarsi di specificare un comportamento predefinito, nel caso in cui non venga fornito alcun identificatore di formato nell'elemento di formato usato nella chiamata al metodo 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. Nell'esempio "N" è l'identificatore di formato predefinito.In the example, "N" is the default format specifier. È pertanto possibile convertire un numero in un numero di telefono formattato specificando un identificatore di formato esplicito.This allows for a number to be converted to a formatted telephone number by providing an explicit format specifier. Nell'esempio riportato di seguito viene illustrata questa chiamata al metodo.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))

L'esecuzione della conversione è possibile anche in assenza di identificatori di formato.But it also allows the conversion to occur if no format specifier is present. Nell'esempio riportato di seguito viene illustrata questa chiamata al metodo.The following example illustrates such a method call.

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

Se non è definito alcun identificatore di formato predefinito, l'implementazione del metodo ICustomFormatter.Format deve includere codice come quello riportato di seguito in modo da permettere a .NET di fornire la formattazione non supportata dal codice.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 questo esempio il metodo che implementa ICustomFormatter.Format ha lo scopo di fungere da metodo di callback per il metodo 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. Di conseguenza, il metodo esamina il parametro formatProvider per determinare se contiene un riferimento all'oggetto TelephoneFormatter corrente.Therefore, it examines the formatProvider parameter to determine whether it contains a reference to the current TelephoneFormatter object. Il metodo può tuttavia essere chiamato anche direttamente dal codice.However, the method can also be called directly from code. In questo caso, è possibile usare il parametro formatProvider per specificare un oggetto CultureInfo o NumberFormatInfo che fornisce informazioni di formattazione specifiche delle impostazioni cultura.In that case, you can use the formatProvider parameter to provide a CultureInfo or NumberFormatInfo object that supplies culture-specific formatting information.

Compilazione del codiceCompiling the Code

Compilare il codice nella riga di comando usando csc.exe o vbc.exe.Compile the code at the command line using csc.exe or vb.exe. Per compilare il codice in Visual Studio, inserirlo in un modello di progetto di applicazione console.To compile the code in Visual Studio, put it in a console application project template.

Vedere ancheSee Also

Esecuzione di operazioni di formattazionePerforming Formatting Operations