Per visualizzare l'articolo in inglese, selezionare la casella di controllo Inglese. È possibile anche visualizzare il testo inglese in una finestra popup posizionando il puntatore del mouse sopra il testo.
Traduzione
Inglese

Procedura: definire e utilizzare provider di formati numerici personalizzati

 

.NET Framework offre un ampio controllo sulla rappresentazione di stringa dei valori numerici.  e supporta le funzionalità seguenti per la personalizzazione del formato dei valori numerici:  

  • Stringhe di formato numerico standard che forniscono un insieme predefinito di formati per la conversione dei numeri nella rispettiva rappresentazione di stringa.  È possibile utilizzarle con qualsiasi metodo di formattazione numerica, come Decimal.ToString(String) che include un parametro format.  Per informazioni dettagliate, vedere Stringhe di formato numerico standard.  

  • Stringhe di formato numerico personalizzate che forniscono un insieme di simboli che possono essere combinati per definire identificatori di formato numerico personalizzati.  È anche possibile utilizzarle con qualsiasi metodo di formattazione numerica, come Decimal.ToString(String) che include un parametro format.  Per informazioni dettagliate, vedere Stringhe di formato numerico personalizzato.  

  • Oggetti CultureInfo o NumberFormatInfo personalizzati che definiscono i simboli e i modelli di formato utilizzati per la visualizzazione delle rappresentazioni di stringa di valori numerici.  È possibile utilizzarli con qualsiasi metodo di formattazione numerica, come ToString che include un parametro provider.  In genere, il parametro provider viene utilizzato per specificare informazioni di formattazione specifiche delle impostazioni cultura.  

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.  .NET Framework consente anche di definire un oggetto di formattazione che non è né un oggetto CultureInfo né un oggetto NumberFormatInfo e consente di determinare la modalità di formattazione di un valore numerico.  In questo argomento sono contenute istruzioni dettagliate per l'implementazione di tale oggetto ed è inoltre riportato un esempio di formattazione di numeri di telefono.  

Per definire un provider di formato personalizzato

  1. Definire una classe che implementa le interfacce IFormatProvider e ICustomFormatter.

  2. Implementare il metodo IFormatProvider.GetFormat.   GetFormat è un metodo di callback che viene richiamato dal metodo di formattazione (ad esempio dal metodo String.Format(IFormatProvider, String, Object[])) per recuperare l'oggetto responsabile della formattazione personalizzata.  Una tipica implementazione di GetFormat effettua le operazioni seguenti:  

    1. Determina se l'oggetto Type passato come parametro di metodo rappresenta un'interfaccia ICustomFormatter.

    2. Se il parametro rappresenta l'interfaccia ICustomFormatter, GetFormat restituisce un oggetto che implementa l'interfaccia ICustomFormatter che è responsabile della formattazione personalizzata.  In genere, l'oggetto di formattazione personalizzata restituisce se stesso.  

    3. Se il parametro non rappresenta l'interfaccia ICustomFormatter, GetFormat restituisce null.

  3. Implementare il metodo Format.  Questo metodo viene chiamato dal metodo String.Format(IFormatProvider, String, Object[]) ed è responsabile della restituzione della rappresentazione di stringa di un numero.  L'implementazione del metodo in genere implica le attività seguenti:  

    1. Facoltativamente, assicurarsi che il metodo sia correttamente destinato a fornire servizi di formattazione esaminando il parametro provider.  Per la formattazione degli oggetti che implementano entrambi i metodi IFormatProvider e ICustomFormatter, questa operazione richiede il test del parametro provider per verificare l'uguaglianza con l'oggetto di formattazione corrente.  

    2. Determinare se l'oggetto di formattazione deve supportare identificatori di formato personalizzati. (Ad esempio, un identificatore di formato "N" potrebbe indicare che un numero di telefono degli Stati Uniti deve essere restituito in formato NANP e una "I" potrebbe indicare l'output in formato ITU-T Recommendation E.123.) Se si utilizzano identificatori di formato, il metodo deve gestire l'identificatore di formato specifico.  Quest'ultimo viene passato al metodo nel parametro format.  Se non è disponibile alcun identificatore, il valore del parametro format è String.Empty.  

    3. Recuperare il valore numerico passato al metodo come parametro arg.  Eseguire le eventuali modifiche necessarie per convertirlo nella relativa rappresentazione di stringa.  

    4. Restituire la rappresentazione di stringa del parametro arg.

Per utilizzare un oggetto di formattazione numerica personalizzata

  1. Creare una nuova istanza della classe di formattazione personalizzata.

  2. Chiamare il metodo di formattazione String.Format(IFormatProvider, String, Object[]), passando l'oggetto di formattazione personalizzata, l'identificatore di formattazione (o String.Empty se non viene utilizzato alcun identificatore) e il valore numerico da formattare.

Esempio

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.  Il metodo gestisce due identificatori di formato, "N" (che restituisce il formato NANP) e "I" (che restituisce il formato E.123 internazionale)."  

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));
   }
}

Il provider di formato numerico personalizzato può essere utilizzato solo con il metodo String.Format(IFormatProvider, String, Object[]).  Gli altri overload dei metodi di formattazione numerica (ad esempio ToString) che hanno un parametro di tipo IFormatProvider passano all'implementazione IFormatProvider.GetFormat un oggetto Type che rappresenta il tipo NumberFormatInfo.  In cambio, prevedono che il metodo restituisca un oggetto NumberFormatInfo.  In caso contrario, il provider di formato numerico personalizzato viene ignorato e al suo posto viene utilizzato l'oggetto NumberFormatInfo relativo alle impostazioni cultura correnti.  Nell'esempio il metodo TelephoneFormatter.GetFormat gestisce la possibilità che possa essere passato erroneamente a un metodo di formattazione numerica esaminando il parametro del metodo e restituendo null se rappresenta un tipo diverso da ICustomFormatter.  

Se un provider di formato numerico personalizzato supporta un insieme 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 utilizzato nella chiamata al metodo String.Format(IFormatProvider, String, Object[]).  Nell'esempio "N" è l'identificatore di formato predefinito.  È pertanto possibile convertire un numero in un numero di telefono formattato mediante la specifica di un identificatore di formato esplicito.  Nell'esempio riportato di seguito viene illustrata questa chiamata al metodo.  

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

L'esecuzione della conversione è possibile anche in assenza di identificatori di formato.  Nell'esempio riportato di seguito viene illustrata questa chiamata al metodo.  

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

Se non è definito alcun identificatore di formato predefinito, l'implementazione del metodo ICustomFormatter.Format deve includere elementi di codice come quelli riportati di seguito in modo da consentire a .NET Framework di fornire la formattazione non supportata dal proprio codice.

if (arg is IFormattable) 
   s = ((IFormattable)arg).ToString(format, formatProvider);
else if (arg != null)    
   s = arg.ToString();

In questo esempio il metodo che implementa ICustomFormatter.Format è destinato a essere utilizzato come metodo di callback per il metodo String.Format(IFormatProvider, String, Object[]).  Tale metodo esamina dunque il parametro formatProvider per determinare se contiene un riferimento all'oggetto TelephoneFormatter corrente.  Il metodo può tuttavia essere chiamato anche direttamente dal codice.  In questo caso è possibile utilizzare il parametro formatProvider per specificare un oggetto CultureInfo o NumberFormatInfo che fornisce informazioni di formattazione specifiche delle impostazioni cultura.  

Compilazione del codice

Compilare il codice alla riga di comando utilizzando csc.exe o vb.exe.  Per compilare il codice in Visual Studio, inserirlo in un modello di progetto di applicazione console.  

Mostra: