Condividi tramite


Formattazione dei tipi di dati

La formattazione è il processo di conversione di un'istanza di una classe, una struttura o un valore di enumerazione nella relativa rappresentazione di stringa, eseguito spesso in modo che la stringa risultante possa essere visualizzata dagli utenti o deserializzata per ripristinare il tipo di dati originale. Questa conversione può comportare le difficoltà seguenti:

  • Il modo in cui i valori vengono archiviati internamente non riflette necessariamente il modo in cui gli utenti desiderano visualizzarli. Un numero di telefono potrebbe ad esempio venire archiviato nel formato 8009999999, che non è di immediata comprensione. Potrebbe invece essere preferibile visualizzarlo come 02 123 456.

  • La conversione di un oggetto nella relativa rappresentazione di stringa non è sempre intuitiva. Non è ad esempio chiaro come dovrebbe venire visualizzata la rappresentazione di stringa di un oggetto Temperature o di un oggetto Person.

  • I valori richiedono spesso una formattazione dipendente dalle impostazioni cultura. In'applicazione in cui vengono utilizzati i numeri per riflettere valori monetari, ad esempio, le stringhe numeriche devono includere il simbolo di valuta, il separatore di gruppi, che nella maggior parte delle impostazioni cultura corrisponde al separatore delle migliaia, e il separatore decimale delle impostazioni cultura correnti.

  • È possibile che in un'applicazione lo stesso valore debba essere visualizzato in diversi modi. È ad esempio possibile che un membro di enumerazione venga rappresentato visualizzando una rappresentazione di stringa del relativo nome oppure visualizzando il relativo valore sottostante.

NotaNota

La formattazione consente di convertire il valore di un tipo in una rappresentazione di stringa,mentre l'analisi è l'operazione inversa.Un'operazione di analisi consente di creare un'istanza di un tipo di dati dalla relativa rappresentazione di stringa.Per informazioni sulla conversione di stringhe in altri tipi di dati, vedere Analisi delle stringhe.

In .NET Framework è disponibile un supporto avanzato della formattazione che consente agli sviluppatori di soddisfare questi requisiti.

In questa panoramica sono incluse le sezioni seguenti:

  • Formattazione in .NET Framework

  • Formattazione predefinita tramite il metodo ToString

  • Override del metodo ToString

  • Metodo ToString e stringhe di formato

  • Provider di formato e interfaccia IFormatProvider

  • Interfaccia IFormattable

  • Formattazione composita

  • Formattazione personalizzata con ICustomFormatter

  • Argomenti correlati

  • Riferimenti

Formattazione in .NET Framework

Il meccanismo di base per la formattazione è costituito dall'implementazione predefinita del metodo Object.ToString, illustrato nella sezione Formattazione predefinita tramite il metodo ToString più avanti in questo argomento. In .NET Framework sono tuttavia disponibili diversi metodi per modificare ed estendere il supporto predefinito della formattazione, tra cui:

  • Override del metodo Object.ToString per definire una rappresentazione di stringa personalizzata del valore di un oggetto. Per ulteriori informazioni, vedere la sezione Override del metodo ToString più avanti in questo argomento.

  • Definizione di identificatori di formato che consentono l'assunzione di più forme da parte della rappresentazione di stringa del valore di un oggetto. L'identificatore di formato "X" nell'istruzione seguente consente, ad esempio, di convertire un valore intero nella rappresentazione di stringa di un valore esadecimale.

    Console.WriteLine(integerValue.ToString("X"))   ' Displays EB98.
    
    Console.WriteLine(integerValue.ToString("X"));   // Displays EB98.
    

    Per ulteriori informazioni sugli identificatori di formato, vedere la sezione Metodo ToString e stringhe di formato.

  • Utilizzo di provider di formato per sfruttare le convenzioni di formattazione di impostazioni cultura specifiche. Nell'istruzione seguente, ad esempio, viene visualizzato un valore di valuta utilizzando le convenzioni di formattazione delle impostazioni cultura en-US.

    Console.WriteLine(cost.ToString("C", New System.Globalization.CultureInfo("en-US")))
    ' The example displays the following output:
    '       $1,632.54
    
    Console.WriteLine(cost.ToString("C", 
                      new System.Globalization.CultureInfo("en-US")));   
    // The example displays the following output:
    //       $1,632.54
    

    Per ulteriori informazioni sulla formattazione con i provider di formato, vedere la sezione Provider di formato e interfaccia IFormatProvider.

  • Implementazione dell'interfaccia IFormattable per supportare sia la conversione di stringa con la classe Convert che la formattazione composita. Per ulteriori informazioni, vedere la sezione Interfaccia IFormattable.

  • Utilizzo della formattazione composita per incorporare la rappresentazione di stringa di un valore in una stringa di dimensioni maggiori. Per ulteriori informazioni, vedere la sezione Formattazione composita.

  • Implementazione di ICustomFormatter e IFormatProvider per fornire una soluzione di formattazione personalizzata completa. Per ulteriori informazioni, vedere la sezione Formattazione personalizzata con ICustomFormatter.

Nelle sezioni seguenti vengono esaminati questi metodi per la conversione di un oggetto nella relativa rappresentazione di stringa.

Torna all'inizio

Formattazione predefinita tramite il metodo ToString

Ogni tipo derivato da System.Object eredita automaticamente un metodo ToString senza parametri che, per impostazione predefinita, restituisce il nome del tipo. Nell'esempio seguente viene illustrato il metodo ToString predefinito. Viene definita una classe denominata Automobile che non dispone di implementazione. Quando viene creata un'istanza della classe e viene chiamato il relativo metodo ToString, viene visualizzato il nome del tipo.

Public Class Automobile
   ' No implementation. All members are inherited from Object.
End Class

Module Example
   Public Sub Main()
      Dim firstAuto As New Automobile()
      Console.WriteLine(firstAuto)
   End Sub
End Module
' The example displays the following output:
'       Automobile
using System;

public class Automobile
{
   // No implementation. All members are inherited from Object.
}

public class Example
{
   public static void Main()
   {
      Automobile firstAuto = new Automobile();
      Console.WriteLine(firstAuto);
   }
}
// The example displays the following output:
//       Automobile

Poiché tutti i tipi diversi dalle interfacce sono derivati da Object, questa funzionalità viene fornita automaticamente alle classi o alle strutture personalizzate. La funzionalità offerta dal metodo ToString predefinito è tuttavia limitata poiché non fornisce informazioni su un'istanza del tipo sebbene consenta di identificarlo. Per fornire una rappresentazione di stringa di un oggetto che fornisce informazioni su tale oggetto, è necessario eseguire l'override del metodo ToString.

NotaNota

Le strutture ereditano dall'oggetto ValueType, che a sua volta viene derivato da Object.Sebbene ValueType esegua l'override di Object.ToString, l'implementazione è identica.

Torna all'inizio

Override del metodo ToString

La visualizzazione del nome di un tipo ha spesso un utilizzo limitato e non consente agli utenti dei tipi di distinguere tra le istanze. È tuttavia possibile eseguire l'override del metodo ToString per fornire una rappresentazione più utile del valore di un oggetto. Nell'esempio seguente viene definito un oggetto Temperature e viene eseguito l'override del relativo metodo ToString per visualizzare la temperatura in gradi Celsius.

Public Class Temperature
   Private temp As Decimal

   Public Sub New(temperature As Decimal)
      Me.temp = temperature
   End Sub

   Public Overrides Function ToString() As String
      Return Me.temp.ToString("N1") + "°C"   
   End Function
End Class

Module Example
   Public Sub Main()
      Dim currentTemperature As New Temperature(23.6d)
      Console.WriteLine("The current temperature is {0}.", currentTemperature)
   End Sub
End Module
' The example displays the following output:
'       The current temperature is 23.6°C.
using System;

public class Temperature
{
   private decimal temp;

   public Temperature(decimal temperature)
   {
      this.temp = temperature;   
   }

   public override string ToString()
   {
      return this.temp.ToString("N1") + "°C";
   }
}

public class Example
{
   public static void Main()
   {
      Temperature currentTemperature = new Temperature(23.6m);
      Console.WriteLine("The current temperature is {0}.", currentTemperature);
   }
}
// The example displays the following output:
//       The current temperature is 23.6°C.

In .NET Framework è stato eseguito l'override del metodo ToString di ogni tipo di valore primitivo per visualizzare il valore dell'oggetto anziché il relativo nome. Nella tabella seguente viene illustrato l'override per ogni tipo primitivo. Si noti che la maggior parte dei metodi sottoposti a override chiama un altro overload del metodo ToString e passa a esso l'identificatore di formato "G", che definisce il formato generale per il tipo, e un oggetto IFormatProvider, che rappresenta le impostazioni cultura correnti.

Tipo

Override di ToString

Boolean

Restituisce Boolean.TrueString o Boolean.FalseString.

Byte

Chiama Byte.ToString("G", NumberFormatInfo.CurrentInfo) per formattare il valore Byte per le impostazioni cultura correnti.

Char

Restituisce il carattere come stringa.

DateTime

Chiama DateTime.ToString("G", DatetimeFormatInfo.CurrentInfo) per formattare il valore di data e ora per le impostazioni cultura correnti.

Decimal

Chiama Decimal.ToString("G", NumberFormatInfo.CurrentInfo) per formattare il valore Decimal per le impostazioni cultura correnti.

Double

Chiama Double.ToString("G", NumberFormatInfo.CurrentInfo) per formattare il valore Double per le impostazioni cultura correnti.

Int16

Chiama Int16.ToString("G", NumberFormatInfo.CurrentInfo) per formattare il valore Int16 per le impostazioni cultura correnti.

Int32

Chiama Int32.ToString("G", NumberFormatInfo.CurrentInfo) per formattare il valore Int32 per le impostazioni cultura correnti.

Int64

Chiama Int64.ToString("G", NumberFormatInfo.CurrentInfo) per formattare il valore Int64 per le impostazioni cultura correnti.

SByte

Chiama SByte.ToString("G", NumberFormatInfo.CurrentInfo) per formattare il valore SByte per le impostazioni cultura correnti.

Single

Chiama Single.ToString("G", NumberFormatInfo.CurrentInfo) per formattare il valore Single per le impostazioni cultura correnti.

UInt16

Chiama UInt16.ToString("G", NumberFormatInfo.CurrentInfo) per formattare il valore UInt16 per le impostazioni cultura correnti.

UInt32

Chiama UInt32.ToString("G", NumberFormatInfo.CurrentInfo) per formattare il valore UInt32 per le impostazioni cultura correnti.

UInt64

Chiama UInt64.ToString("G", NumberFormatInfo.CurrentInfo) per formattare il valore UInt64 per le impostazioni cultura correnti.

Torna all'inizio

Metodo ToString e stringhe di formato

L'utilizzo del metodo ToString predefinito o l'esecuzione dell'override di ToString è un'operazione appropriata quando un oggetto dispone di una singola rappresentazione di stringa. Spesso, tuttavia, il valore di un oggetto dispone di più rappresentazioni. È ad esempio possibile esprimere una temperatura in gradi Fahrenheit, gradi Celsius o gradi Kelvin. Analogamente, il valore intero 10 può essere rappresentato in diversi modi, tra cui 10, 10,0, 1.0e01 o €10,00.

Per consentire a un singolo valore di disporre di più rappresentazioni di stringa, in .NET Framework vengono utilizzate le stringhe di formato. Una stringa di formato è una stringa che contiene uno o più identificatori di formato predefiniti costituiti da singoli caratteri o gruppi di caratteri che definiscono il modo in cui deve essere formattato l'output del metodo ToString. La stringa di formato viene quindi passata come parametro al metodo ToString dell'oggetto per determinare come deve venire visualizzata la rappresentazione di stringa del valore di tale oggetto.

Tutti i tipi numerici, di data e ora e di enumerazione in .NET Framework supportano un set predefinito di identificatori di formato. È anche possibile utilizzare le stringhe di formato per definire più rappresentazioni di stringa dei tipi di dati definiti dall'applicazione.

Stringhe di formato standard

Una stringa di formato standard contiene un singolo identificatore di formato, che è un carattere alfabetico che definisce la rappresentazione di stringa dell'oggetto a cui viene applicata, insieme a un identificatore di precisione facoltativo, che influisce sul numero di cifre visualizzate nella stringa di risultato. Se l'identificatore di precisione viene omesso o non è supportato, un identificatore di formato standard è equivalente a una stringa di formato standard.

In .NET Framework viene definito un set di identificatori di formato standard per tutti i tipi numerici, di data e ora e di enumerazione. Ognuna di queste categorie supporta, ad esempio, un identificatore di formato standard "G", che definisce una rappresentazione di stringa generale di un valore di tale tipo.

Le stringhe di formato standard per i tipi di enumerazione controllano direttamente la rappresentazione di stringa di un valore. Le stringhe di formato passate al metodo ToString del valore di un'enumerazione determinano se il valore viene visualizzato tramite il relativo nome di stringa (identificatori di formato "G" e "F"), il relativo valore integrale sottostante (identificatore di formato "D") oppure il relativo valore esadecimale (identificatore di formato "X"). Nell'esempio seguente viene illustrato l'utilizzo delle stringhe di formato standard per formattare un valore dell'enumerazione DayOfWeek.

Dim thisDay As DayOfWeek = DayOfWeek.Monday
Dim formatStrings() As String = {"G", "F", "D", "X"}

For Each formatString As String In formatStrings
   Console.WriteLine(thisDay.ToString(formatString))
Next
' The example displays the following output:
'       Monday
'       Monday
'       1
'       00000001
DayOfWeek thisDay = DayOfWeek.Monday;
string[] formatStrings = {"G", "F", "D", "X"};

foreach (string formatString in formatStrings)
   Console.WriteLine(thisDay.ToString(formatString));
// The example displays the following output:
//       Monday
//       Monday
//       1
//       00000001

Per informazioni sulle stringhe di formato di enumerazione, vedere Stringhe di formato di enumerazione.

Le stringhe di formato standard per i tipi numerici definiscono in genere una stringa di risultato il cui aspetto preciso viene controllato da uno o più valori delle proprietà. L'identificatore di formato "C", ad esempio, consente di formattare un numero come valore di valuta. Quando si chiama il metodo ToString con l'identificatore di formato "C" come unico parametro, vengono utilizzati i valori delle proprietà seguenti dell'oggetto NumberFormatInfo delle impostazioni cultura correnti per definire la rappresentazione di stringa del valore numerico:

  • Proprietà CurrencySymbol, che specifica il simbolo di valuta delle impostazioni cultura correnti.

  • Proprietà CurrencyNegativePattern o CurrencyPositivePattern, che restituisce un valore intero che determina gli aspetti seguenti:

    • Posizione del simbolo di valuta.

    • Utilizzo di un segno negativo iniziale, di un segno negativo finale o di parentesi per indicare i valori negativi.

    • Inserimento di uno spazio tra il valore numerico e il simbolo di valuta.

  • Proprietà CurrencyDecimalDigits, che definisce il numero di cifre frazionarie nella stringa di risultato.

  • Proprietà CurrencyDecimalSeparator, che definisce il simbolo del separatore decimale nella stringa di risultato.

  • Proprietà CurrencyGroupSeparator, che definisce il simbolo del separatore di gruppi.

  • Proprietà CurrencyGroupSizes, che definisce il numero di cifre in ogni gruppo a sinistra del separatore decimale.

  • Proprietà NegativeSign, che determina il segno negativo utilizzato nella stringa di risultato se non vengono utilizzate parentesi per indicare i valori negativi.

Le stringhe di formato numerico possono inoltre includere un identificatore di precisione. Il significato di questo identificatore dipende dalla stringa di formato con la quale viene utilizzato, ma in genere esso indica il numero totale di cifre o il numero di cifre frazionarie che devono essere presenti nella stringa di risultato. Nell'esempio seguente vengono utilizzati, ad esempio, la stringa numerica standard "X4"e un identificatore di precisione per creare un valore stringa con quattro cifre esadecimali.

Dim byteValues() As Byte = { 12, 163, 255 }
For Each byteValue As Byte In byteValues
   Console.WriteLine(byteValue.ToString("X4"))
Next
' The example displays the following output:
'       000C
'       00A3
'       00FF
byte[] byteValues = { 12, 163, 255 };
foreach (byte byteValue in byteValues)
   Console.WriteLine(byteValue.ToString("X4"));
// The example displays the following output:
//       000C
//       00A3
//       00FF

Per ulteriori informazioni sulle stringhe di formattazione numerica standard, vedere Stringhe di formato numerico standard.

Le stringhe di formato standard per i valori di data e ora sono alias per stringhe di formato personalizzate archiviate da una proprietà DateTimeFormatInfo specifica. Se viene chiamato, ad esempio, il metodo ToString di un valore di data e ora con l'identificatore di formato "D", la data e l'ora vengono visualizzate utilizzando la stringa di formato personalizzata archiviata nella proprietà DateTimeFormatInfo.LongDatePattern delle impostazioni cultura correnti. Per ulteriori informazioni sulle stringhe di formato personalizzate, vedere la sezione successiva. Nell'esempio seguente viene illustrata questa relazione.

Imports System.Globalization

Module Example
   Public Sub Main()
      Dim date1 As Date = #6/30/2009#
      Console.WriteLine("D Format Specifier:     {0:D}", date1)
      Dim longPattern As String = CultureInfo.CurrentCulture.DateTimeFormat.LongDatePattern
      Console.WriteLine("'{0}' custom format string:     {1}", _
                        longPattern, date1.ToString(longPattern))
   End Sub
End Module
' The example displays the following output when run on a system whose
' current culture is en-US:
'    D Format Specifier:     Tuesday, June 30, 2009
'    'dddd, MMMM dd, yyyy' custom format string:     Tuesday, June 30, 2009
using System;
using System.Globalization;

public class Example
{
   public static void Main()
   {
      DateTime date1 = new DateTime(2009, 6, 30);
      Console.WriteLine("D Format Specifier:     {0:D}", date1);
      string longPattern = CultureInfo.CurrentCulture.DateTimeFormat.LongDatePattern;
      Console.WriteLine("'{0}' custom format string:     {1}", 
                        longPattern, date1.ToString(longPattern));
   }
}
// The example displays the following output when run on a system whose
// current culture is en-US:
//    D Format Specifier:     Tuesday, June 30, 2009
//    'dddd, MMMM dd, yyyy' custom format string:     Tuesday, June 30, 2009

Per ulteriori informazioni sulle stringhe di formato di data e ora standard, vedere Stringhe di formato di data e ora standard.

È inoltre possibile utilizzare le stringhe di formato standard per definire la rappresentazione di stringa di un oggetto definito dall'applicazione, prodotta dal metodo ToString(String) dell'oggetto. È possibile definire gli identificatori di formato standard specifici supportati dall'oggetto, nonché determinare se per essi viene fatta o meno distinzione tra maiuscole e minuscole. L'implementazione del metodo ToString(String) deve supportare gli elementi seguenti:

  • Un identificatore di formato "G" che rappresenta un formato abituale o comune dell'oggetto. L'overload senza parametri del metodo ToString dell'oggetto deve chiamare il relativo overload di ToString(String) e passare a esso la stringa di formato standard "G".

  • Supporto per un identificatore di formato equivalente a un riferimento Null (Nothing in Visual Basic). Un identificatore di formato equivalente a un riferimento Null deve essere considerato equivalente all'identificatore di formato "G".

Una classe Temperature può, ad esempio, archiviare internamente la temperatura in gradi Celsius e utilizzare gli identificatori di formato per rappresentare il valore dell'oggetto Temperature in gradi Celsius, gradi Fahrenheit e gradi Kelvin. Nell'esempio seguente viene illustrato questo concetto.

Public Class Temperature
   Private m_Temp As Decimal

   Public Sub New(temperature As Decimal)
      Me.m_Temp = temperature
   End Sub

   Public ReadOnly Property Celsius() As Decimal
      Get
         Return Me.m_Temp
      End Get   
   End Property

   Public ReadOnly Property Kelvin() As Decimal
      Get
         Return Me.m_Temp + 273.15d   
      End Get
   End Property

   Public ReadOnly Property Fahrenheit() As Decimal
      Get
         Return Math.Round(CDec(Me.m_Temp * 9 / 5 + 32), 2)
      End Get      
   End Property

   Public Overrides Function ToString() As String
      Return Me.ToString("C")
   End Function

   Public Overloads Function ToString(format As String) As String  
      ' Handle null or empty string.
      If String.IsNullOrEmpty(format) Then format = "C"
      ' Remove spaces and convert to uppercase.
      format = format.Trim().ToUpperInvariant()      

      ' Convert temperature to Fahrenheit and return string.
      Select Case format
         Case "F"
            Return Me.Fahrenheit.ToString("N2") & " °F"
         ' Convert temperature to Kelvin and return string.
         Case "K"
            Return Me.Kelvin.ToString("N2") & " K"
         ' Return temperature in Celsius.
         Case "C"
            Return Me.Celsius.ToString("N2") & " °C"
         Case Else
            Throw New FormatException(String.Format("The '{0}' format string is not supported.", format))
      End Select      
   End Function
End Class

Public Module Example
   Public Sub Main()
      Dim temp1 As New Temperature(0d)
      Console.WriteLine(temp1.ToString())
      Console.WriteLine(temp1.ToString("C"))
      Console.WriteLine(temp1.ToString("F"))
      Console.WriteLine(temp1.ToString("K"))
      Dim temp2 As New Temperature(-40d)
      Console.WriteLine(temp2.ToString())
      Console.WriteLine(temp2.ToString("C"))
      Console.WriteLine(temp2.ToString("F"))
      Console.WriteLine(temp2.ToString("K"))
      Dim temp3 As New Temperature(16d)
      Console.WriteLine(temp3.ToString())
      Console.WriteLine(temp3.ToString("C"))
      Console.WriteLine(temp3.ToString("F"))
      Console.WriteLine(temp3.ToString("K"))

      Console.WriteLine(String.Format("The temperature is now {0:F}.", temp3))
   End Sub
End Module
' The example displays the following output:
'       0.00 °C
'       0.00 °C
'       32.00 °F
'       273.15 K
'       -40.00 °C
'       -40.00 °C
'       -40.00 °F
'       233.15 K
'       16.00 °C
'       16.00 °C
'       60.80 °F
'       289.15 K
'       The temperature is now 16.00 °C.
public class Temperature
{
   private decimal m_Temp;

   public Temperature(decimal temperature)
   {
      this.m_Temp = temperature;
   }

   public decimal Celsius
   {
      get { return this.m_Temp; }
   }

   public decimal Kelvin
   {
      get { return this.m_Temp + 273.15m; }   
   }

   public decimal Fahrenheit
   {
      get { return Math.Round(((decimal) (this.m_Temp * 9 / 5 + 32)), 2); }
   }

   public override string ToString()
   {
      return this.ToString("C");
   }

   public string ToString(string format)
   {  
      // Handle null or empty string.
      if (String.IsNullOrEmpty(format)) format = "C";
      // Remove spaces and convert to uppercase.
      format = format.Trim().ToUpperInvariant();      

      // Convert temperature to Fahrenheit and return string.
      switch (format)
      {
         // Convert temperature to Fahrenheit and return string.
         case "F":
            return this.Fahrenheit.ToString("N2") + " °F";
         // Convert temperature to Kelvin and return string.
         case "K":
            return this.Kelvin.ToString("N2") + " K";
         // return temperature in Celsius.
         case "C":
            return this.Celsius.ToString("N2") + " °C";
         default:
            throw new FormatException(String.Format("The '{0}' format string is not supported.", format));
      }      
   }
}

public class Example
{
   public static void Main()
   {
      Temperature temp1 = new Temperature(0m);
      Console.WriteLine(temp1.ToString());
      Console.WriteLine(temp1.ToString("C"));
      Console.WriteLine(temp1.ToString("F"));
      Console.WriteLine(temp1.ToString("K"));
      Temperature temp2 = new Temperature(-40m);
      Console.WriteLine(temp2.ToString());
      Console.WriteLine(temp2.ToString("C"));
      Console.WriteLine(temp2.ToString("F"));
      Console.WriteLine(temp2.ToString("K"));
      Temperature temp3 = new Temperature(16m);
      Console.WriteLine(temp3.ToString());
      Console.WriteLine(temp3.ToString("C"));
      Console.WriteLine(temp3.ToString("F"));
      Console.WriteLine(temp3.ToString("K"));

      Console.WriteLine(String.Format("The temperature is now {0:F}.", temp3));
   }
}
// The example displays the following output:
//       0.00 °C
//       0.00 °C
//       32.00 °F
//       273.15 K
//       -40.00 °C
//       -40.00 °C
//       -40.00 °F
//       233.15 K
//       16.00 °C
//       16.00 °C
//       60.80 °F
//       289.15 K
//       The temperature is now 16.00 °C.

Torna all'inizio

Stringhe di formato personalizzate

Oltre alle stringhe di formato standard, in .NET Framework sono definite stringhe di formato personalizzate sia per valori numerici che per valori di data e ora. Una stringa di formato personalizzata è costituita da uno o più identificatori di formato personalizzati che definiscono la rappresentazione di stringa di un valore. La stringa di formato di data e ora personalizzata "yyyy/mm/dd hh:mm:ss.ffff t zzz" consente, ad esempio, di convertire una data nella relativa rappresentazione di stringa nel formato "2008/11/15 07:45:00.0000 P -08:00" per le impostazioni cultura en-US. Analogamente, la stringa di formato personalizzata "0000" consente di convertire il valore intero 12 in "0012". Per un elenco completo di stringhe di formato personalizzate, vedere Stringhe di formato data e ora personalizzate e Stringhe di formato numerico personalizzate.

Se una stringa di formato è costituita da un solo identificatore di formato personalizzato, l'identificatore di formato deve essere preceduto dal simbolo di percentuale (%) per evitare confusione con un identificatore di formato standard. Nell'esempio seguente viene utilizzato l'identificatore di formato personalizzato "M" per visualizzare un numero a una cifra o a due cifre del mese di una data specifica.

Dim date1 As Date = #09/08/2009#
Console.WriteLine(date1.ToString("%M"))      ' Displays 9
DateTime date1 = new DateTime(2009, 9, 8);
Console.WriteLine(date1.ToString("%M"));       // Displays 9

Numerose stringhe di formato standard per i valori di data e ora sono alias per stringhe di formato personalizzate definite dalle proprietà dell'oggetto DateTimeFormatInfo. Le stringhe di formato personalizzate offrono inoltre una notevole flessibilità in quanto consentono una formattazione definita dall'applicazione per valori numerici o di data e ora. È possibile definire stringhe di risultato personalizzate sia per valori numerici che per valori di data e ora combinando più identificatori di formato personalizzati in una singola stringa di formato personalizzata. Nell'esempio seguente viene definita una stringa di formato personalizzata che consente di visualizzare il giorno della settimana tra parentesi dopo il nome del mese, il giorno e l'anno.

Dim customFormat As String = "MMMM dd, yyyy (dddd)"
Dim date1 As Date = #8/28/2009#
Console.WriteLine(date1.ToString(customFormat))   
' The example displays the following output if run on a system
' whose language is English:
'       August 28, 2009 (Friday)      
string customFormat = "MMMM dd, yyyy (dddd)";
DateTime date1 = new DateTime(2009, 8, 28);
Console.WriteLine(date1.ToString(customFormat));   
// The example displays the following output if run on a system
// whose language is English:
//       August 28, 2009 (Friday)      

Sebbene le stringhe di formato standard consentano in genere di gestire la maggior parte delle necessità relative alla formattazione per i tipi definiti dall'applicazione, è anche possibile definire identificatori di formato personalizzati per formattare i tipi.

Torna all'inizio

Provider di formato e interfaccia IFormatProvider

Sebbene gli identificatori di formato consentano di personalizzare la formattazione degli oggetti, la creazione di una rappresentazione di stringa significativa degli oggetti richiede spesso informazioni aggiuntive sulla formattazione. La formattazione, ad esempio, di un numero come valore di valuta tramite la stringa di formato standard "C" o una stringa di formato personalizzata, come ad esempio "$ #,#.00", richiede almeno la possibilità di includere nella stringa formattata le informazioni relative al simbolo di valuta, al separatore di gruppi e al separatore decimale corretti. In .NET Framework queste informazioni aggiuntive sulla formattazione vengono rese disponibili tramite l'interfaccia IFormatProvider, fornita come parametro di uno o più overload del metodo ToString di tipi numerici e di data e ora. Nell'esempio seguente viene illustrato come cambia la rappresentazione di stringa di un oggetto quando viene formattata con tre oggetti IFormatProvider diversi.

Imports System.Globalization

Public Module Example
   Public Sub Main()
      Dim value As Decimal = 1603.42d
      Console.WriteLine(value.ToString("C3", New CultureInfo("en-US")))
      Console.WriteLine(value.ToString("C3", New CultureInfo("fr-FR")))
      Console.WriteLine(value.ToString("C3", New CultureInfo("de-DE")))
   End Sub
End Module
' The example displays the following output:
'       $1,603.420
'       1 603,420 €
'       1.603,420 €
using System;
using System.Globalization;

public class Example
{
   public static void Main()
   {
      decimal value = 1603.42m;
      Console.WriteLine(value.ToString("C3", new CultureInfo("en-US")));
      Console.WriteLine(value.ToString("C3", new CultureInfo("fr-FR")));
      Console.WriteLine(value.ToString("C3", new CultureInfo("de-DE")));
   }
}
// The example displays the following output:
//       $1,603.420
//       1 603,420 €
//       1.603,420 €

L'interfaccia IFormatProvider include un metodo, GetFormat(Type), che dispone di un singolo parametro che specifica il tipo di oggetto che fornisce informazioni sulla formattazione. Se il metodo può fornire un oggetto di tale tipo, lo restituisce. In caso contrario, restituisce un riferimento Null (Nothing in Visual Basic).

IFormatProvider.GetFormat è un metodo di callback. Quando si chiama un overload del metodo ToString che include un parametro IFormatProvider, viene chiamato il metodo GetFormat di tale oggetto IFormatProvider. Il metodo GetFormat è responsabile della restituzione di un oggetto che fornisce le informazioni sulla formattazione necessarie, specificate dal relativo parametro formatType, al metodo ToString.

Diversi metodi di conversione di stringhe o di formattazione includono un parametro di tipo IFormatProvider, ma in molti casi il valore del parametro viene ignorato quando il metodo viene chiamato. Nella tabella seguente sono elencati alcuni dei metodi di formattazione che utilizzano il parametro e il tipo dell'oggetto Type che passano al metodo IFormatProvider.GetFormat.

Metodo

Tipo di parametro formatType

Metodo ToString di tipi numerici

System.Globalization.NumberFormatInfo

Metodo ToString di tipi di data e ora

System.Globalization.DateTimeFormatInfo

String.Format

System.ICustomFormatter

StringBuilder.AppendFormat

System.ICustomFormatter

NotaNota

I metodi ToString dei tipi numerici e di data e ora sono sottoposti a overload e solo alcuni degli overload includono un parametro IFormatProvider.Se un metodo non dispone di un parametro di tipo IFormatProvider, al suo posto viene passato l'oggetto restituito dalla proprietà CultureInfo.CurrentCulture.Una chiamata al metodo Int32.ToString() predefinito comporta, ad esempio, in definitiva, una chiamata al metodo come la seguente: Int32.ToString("G", System.Globalization.CultureInfo.CurrentCulture).

In .NET Framework sono disponibili tre classi che implementano IFormatProvider:

  • DateTimeFormatInfo, una classe che fornisce informazioni sulla formattazione per i valori di data e ora per impostazioni cultura specifiche. L'implementazione del metodo IFormatProvider.GetFormat della classe restituisce un'istanza della classe stessa.

  • NumberFormatInfo, una classe che fornisce informazioni sulla formattazione numerica per impostazioni cultura specifiche. L'implementazione del metodo IFormatProvider.GetFormat della classe restituisce un'istanza della classe stessa.

  • CultureInfo. L'implementazione del metodo IFormatProvider.GetFormat della classe può restituire un oggetto NumberFormatInfo per fornire informazioni sulla formattazione numerica o un oggetto DateTimeFormatInfo per fornire informazioni sulla formattazione per i valori di data e ora.

È anche possibile implementare un provider di formato personalizzato per sostituire una di queste classi. Il metodo GetFormat dell'implementazione, tuttavia, deve restituire un oggetto del tipo elencato nella tabella precedente, se deve fornire informazioni sulla formattazione al metodo ToString.

Torna all'inizio

Interfaccia IFormattable

In genere, i tipi che eseguono l'overload del metodo ToString con una stringa di formato e un parametro IFormatProvider implementano anche l'interfaccia IFormattable. Questa interfaccia dispone di un singolo membro, IFormattable.ToString(String, IFormatProvider), che include sia una stringa di formato che un provider di formato come parametri.

L'implementazione dell'interfaccia IFormattable per la classe definita dall'applicazione offre due vantaggi:

  • Supporto per la conversione di stringhe da parte della classe Convert. Le chiamate ai metodi Convert.ToString(Object) e Convert.ToString(Object, IFormatProvider) comportano una chiamata direttamente all'implementazione di IFormattable.

  • Supporto per la formattazione composita. Se viene utilizzato un elemento di formato che include una stringa di formato per formattare il tipo personalizzato, tramite Common Language Runtime viene chiamata automaticamente l'implementazione di IFormattable, che viene passata alla stringa di formato. Per ulteriori informazioni sulla formattazione composita con metodi come String.Format o Console.WriteLine, vedere la sezione Formattazione composita.

Nell'esempio seguente viene definita una classe Temperature che implementa l'interfaccia IFormattable. Sono supportati gli identificatori di formato "C" e "G" per visualizzare la temperatura in Celsius, l'identificatore di formato "F" per visualizzare la temperatura in Fahrenheit e l'identificatore di formato "K" per visualizzare la temperatura in Kelvin.

Imports System.Globalization

Public Class Temperature : Implements IFormattable
   Private m_Temp As Decimal

   Public Sub New(temperature As Decimal)
      Me.m_Temp = temperature
   End Sub

   Public ReadOnly Property Celsius() As Decimal
      Get
         Return Me.m_Temp
      End Get   
   End Property

   Public ReadOnly Property Kelvin() As Decimal
      Get
         Return Me.m_Temp + 273.15d   
      End Get
   End Property

   Public ReadOnly Property Fahrenheit() As Decimal
      Get
         Return Math.Round(CDec(Me.m_Temp * 9 / 5 + 32), 2)
      End Get      
   End Property

   Public Overrides Function ToString() As String
      Return Me.ToString("G", Nothing)
   End Function

   Public Overloads Function ToString(format As String) As String
      Return Me.ToString(format, Nothing)
   End Function

   Public Overloads Function ToString(format As String, provider As IFormatProvider) As String _  
      Implements IFormattable.ToString

      ' Handle null or empty arguments.
      If String.IsNullOrEmpty(format) Then format = "G"
      ' Remove any white space and convert to uppercase.
      format = format.Trim().ToUpperInvariant()

      If provider Is Nothing Then provider = NumberFormatInfo.CurrentInfo

      Select Case format
         ' Convert temperature to Fahrenheit and return string.
         Case "F"
            Return Me.Fahrenheit.ToString("N2", provider) & "°F"
         ' Convert temperature to Kelvin and return string.
         Case "K"
            Return Me.Kelvin.ToString("N2", provider) & "K"
         ' Return temperature in Celsius.
         Case "C", "G"
            Return Me.Celsius.ToString("N2", provider) & "°C"
         Case Else
            Throw New FormatException(String.Format("The '{0}' format string is not supported.", format))
      End Select      
   End Function
End Class
using System;
using System.Globalization;

public class Temperature : IFormattable
{
   private decimal m_Temp;

   public Temperature(decimal temperature)
   {
      this.m_Temp = temperature;
   }

   public decimal Celsius
   {
      get { return this.m_Temp; }
   }

   public decimal Kelvin
   {
      get { return this.m_Temp + 273.15m; }   
   }

   public decimal Fahrenheit
   {
      get { return Math.Round((decimal) this.m_Temp * 9 / 5 + 32, 2); }
   }

   public override string ToString()
   {
      return this.ToString("G", null);
   }

   public string ToString(string format)
   {
      return this.ToString(format, null);
   }

   public string ToString(string format, IFormatProvider provider)  
   {
      // Handle null or empty arguments.
      if (String.IsNullOrEmpty(format)) format = "G";
      // Remove any white space and convert to uppercase.
      format = format.Trim().ToUpperInvariant();

      if (provider == null) provider = NumberFormatInfo.CurrentInfo;

      switch (format)
      {
         // Convert temperature to Fahrenheit and return string.
         case "F":
            return this.Fahrenheit.ToString("N2", provider) + "°F";
         // Convert temperature to Kelvin and return string.
         case "K":
            return this.Kelvin.ToString("N2", provider) + "K";
         // Return temperature in Celsius.
         case "C":
         case "G":
            return this.Celsius.ToString("N2", provider) + "°C";
         default:
            throw new FormatException(String.Format("The '{0}' format string is not supported.", format));
      }      
   }
}

Nell'esempio seguente viene creata un'istanza di un oggetto Temperature. Viene quindi chiamato il metodo ToString e vengono utilizzate diverse stringhe di formato composite per ottenere diverse rappresentazioni di stringa di un oggetto Temperature. Ognuna di queste chiamate al metodo chiama, a sua volta, l'implementazione di IFormattable della classe Temperature.

Public Module Example
   Public Sub Main()
      Dim temp1 As New Temperature(22d)
      Console.WriteLine(Convert.ToString(temp1, New CultureInfo("ja-JP")))
      Console.WriteLine("Temperature: {0:K}", temp1)
      Console.WriteLine("Temperature: {0:F}", temp1)
      Console.WriteLine(String.Format(New CultureInfo("fr-FR"), "Temperature: {0:F}", temp1)) 
   End Sub
End Module
' The example displays the following output:
'       22.00°C
'       Temperature: 295.15°K
'       Temperature: 71.60°F
'       Temperature: 71,60°F
public class Example
{
   public static void Main()
   {
      Temperature temp1 = new Temperature(22m);
      Console.WriteLine(Convert.ToString(temp1, new CultureInfo("ja-JP")));
      Console.WriteLine("Temperature: {0:K}", temp1);
      Console.WriteLine("Temperature: {0:F}", temp1);
      Console.WriteLine(String.Format(new CultureInfo("fr-FR"), "Temperature: {0:F}", temp1));
   }
}
// The example displays the following output:
//       22.00°C
//       Temperature: 295.15°K
//       Temperature: 71.60°F
//       Temperature: 71,60°F

Torna all'inizio

Formattazione composita

Alcuni metodi, ad esempio String.Format e StringBuilder.AppendFormat, supportano la formattazione composita. Una stringa di formato composita è un tipo di modello che restituisce una singola stringa che incorpora la rappresentazione di stringa di zero, uno o più oggetti. Ogni oggetto è rappresentato nella stringa di formato composita da un elemento di formato indicizzato. L'indice dell'elemento di formato corrisponde alla posizione dell'oggetto che esso rappresenta nell'elenco di parametri del metodo. Gli indici sono a base zero. Nella chiamata al metodo String.Format seguente, ad esempio, il primo elemento di formato, {0:D}, viene sostituito dalla rappresentazione di stringa di thatDate, il secondo elemento di formato, {1}, viene sostituito dalla rappresentazione di stringa di item1 e il terzo elemento di formato, {2:C2}, viene sostituito dalla rappresentazione di stringa di item1.Value.

result = String.Format("On {0:d}, the inventory of {1} was worth {2:C2}.", _
                       thatDate, item1, item1.Value)
Console.WriteLine(result)                            
' The example displays output like the following if run on a system
' whose current culture is en-US:
'       On 5/1/2009, the inventory of WidgetA was worth $107.44.
result = String.Format("On {0:d}, the inventory of {1} was worth {2:C2}.", 
                       thatDate, item1, item1.Value);
Console.WriteLine(result);                            
// The example displays output like the following if run on a system
// whose current culture is en-US:
//       On 5/1/2009, the inventory of WidgetA was worth $107.44.

Per ulteriori informazioni sulla formattazione composita, vedere Formattazione composta.

Torna all'inizio

Formattazione personalizzata con ICustomFormatter

Alcuni metodi di formattazione composita, ad esempio [M:System.String.Format(System.IFormatProvider,System.String,System.Object[])eM:System.Text.StringBuilder.AppendFormat(System.IFormatProvider,System.String,System.Object[])], includono un parametro del provider di formato che supporta la formattazione personalizzata. Quando il metodo di formattazione viene chiamato, passa un oggetto Type che rappresenta un'interfaccia ICustomFormatter del metodo GetFormat del provider di formato. Il metodo GetFormat è quindi responsabile della restituzione dell'implementazione di ICustomFormatter che fornisce formattazione personalizzata.

L'interfaccia ICustomFormatter dispone di un singolo metodo, Format(String, Object, IFormatProvider), chiamato automaticamente da un metodo di formattazione composita una volta per ogni elemento di formato in una stringa di formato composita. Il metodo Format(String, Object, IFormatProvider) dispone di tre parametri: una stringa di formato, che rappresenta l'argomento formatString in un elemento di formato, un oggetto da formattare e un oggetto IFormatProvider che fornisce i servizi di formattazione. In genere, la classe che implementa ICustomFormatter implementa anche IFormatProvider, pertanto quest'ultimo parametro è un riferimento alla classe di formattazione personalizzata stessa. Questo metodo restituisce una rappresentazione di stringa formattata personalizzata dell'oggetto da formattare. Se il metodo non è in grado di formattare l'oggetto, deve restituire un riferimento Null (Nothing in Visual Basic).

Nell'esempio seguente viene fornita un'implementazione di ICustomFormatter denominata ByteByByteFormatter che consente di visualizzare i valori interi come sequenza di valori esadecimali a due cifre seguiti da uno spazio.

Public Class ByteByByteFormatter : 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

      If Not formatProvider.Equals(Me) Then Return Nothing

      ' Handle only hexadecimal format string.
      If Not fmt.StartsWith("X") Then 
            Return Nothing
      End If

      ' Handle only integral types.
      If Not typeof arg Is Byte AndAlso
         Not typeof arg Is Int16 AndAlso
         Not typeof arg Is Int32 AndAlso
         Not typeof arg Is Int64 AndAlso
         Not typeof arg Is SByte AndAlso
         Not typeof arg Is UInt16 AndAlso
         Not typeof arg Is UInt32 AndAlso
         Not typeof arg Is UInt64 Then _
            Return Nothing

      Dim bytes() As Byte = BitConverter.GetBytes(arg)
      Dim output As String = Nothing

      For ctr As Integer = bytes.Length - 1 To 0 Step -1
         output += String.Format("{0:X2} ", bytes(ctr))   
      Next

      Return output.Trim()
   End Function
End Class
public class ByteByByteFormatter : 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)
   {   
      if (! formatProvider.Equals(this)) return null;

      // Handle only hexadecimal format string.
      if (! format.StartsWith("X")) return null;

      byte[] bytes;
      string output = null;

      // Handle only integral types.
      if (arg is Byte) 
         bytes = BitConverter.GetBytes((Byte) arg);
      else if (arg is Int16)
         bytes = BitConverter.GetBytes((Int16) arg);
      else if (arg is Int32)
         bytes = BitConverter.GetBytes((Int32) arg);
      else if (arg is Int64)   
         bytes = BitConverter.GetBytes((Int64) arg);
      else if (arg is SByte)
         bytes = BitConverter.GetBytes((SByte) arg);
      else if (arg is UInt16)
         bytes = BitConverter.GetBytes((UInt16) arg);
      else if (arg is UInt32)
         bytes = BitConverter.GetBytes((UInt32) arg);
      else if (arg is UInt64)
         bytes = BitConverter.GetBytes((UInt64) arg);
      else
         return null;

      for (int ctr = bytes.Length - 1; ctr >= 0; ctr--)
         output += String.Format("{0:X2} ", bytes[ctr]);   

      return output.Trim();
   }
}

Nell'esempio seguente viene utilizzata la classe ByteByByteFormatter per formattare valori interi. Si noti che il metodo ICustomFormatter.Format viene chiamato più di una volta nella seconda chiamata al metodo String.Format(IFormatProvider, String, Object[]) e che il provider NumberFormatInfo predefinito viene utilizzato nella terza chiamata al metodo, in quanto il metodo ByteByByteFormatter.Format non riconosce la stringa di formato "N0" e restituisce un riferimento Null (Nothing in Visual Basic).

Public Module Example
   Public Sub Main()
      Dim value As Long = 3210662321 
      Dim value1 As Byte = 214
      Dim value2 As Byte = 19

      Console.WriteLine((String.Format(New ByteByByteFormatter(), "{0:X}", value)))
      Console.WriteLine((String.Format(New ByteByByteFormatter(), "{0:X} And {1:X} = {2:X} ({2:000})", 
                                      value1, value2, value1 And value2)))                                
      Console.WriteLine(String.Format(New ByteByByteFormatter(), "{0,10:N0}", value))
   End Sub
End Module
' The example displays the following output:
'       00 00 00 00 BF 5E D1 B1
'       00 D6 And 00 13 = 00 12 (018)
'       3,210,662,321
public class Example
{
   public static void Main()
   {
      long value = 3210662321; 
      byte value1 = 214;
      byte value2 = 19;

      Console.WriteLine(String.Format(new ByteByByteFormatter(), "{0:X}", value));
      Console.WriteLine(String.Format(new ByteByByteFormatter(), "{0:X} And {1:X} = {2:X} ({2:000})", 
                                      value1, value2, value1 & value2));                                
      Console.WriteLine(String.Format(new ByteByByteFormatter(), "{0,10:N0}", value));
   }
}
// The example displays the following output:
//       00 00 00 00 BF 5E D1 B1
//       00 D6 And 00 13 = 00 12 (018)
//       3,210,662,321

Torna all'inizio

Argomenti correlati

Titolo

Definizione

Stringhe di formato numerico standard

Vengono descritte le stringhe di formato standard che consentono di creare rappresentazioni di stringa utilizzate comunemente di valori numerici.

Stringhe di formato numerico personalizzate

Vengono descritte le stringhe di formato personalizzate che consentono di creare formati specifici dell'applicazione per valori numerici.

Stringhe di formato di data e ora standard

Vengono descritte le stringhe di formato standard che consentono di creare rappresentazioni di stringa utilizzate comunemente di valori DateTime.

Stringhe di formato data e ora personalizzate

Vengono descritte le stringhe di formato personalizzate che consentono di creare formati specifici dell'applicazione per valori DateTime.

Stringhe di formato TimeSpan standard

Vengono descritte le stringhe di formato standard che consentono di creare rappresentazioni di stringa utilizzate comunemente di intervalli di tempo.

Stringhe di formato TimeSpan personalizzate

Vengono descritte le stringhe di formato personalizzate che consentono di creare formati specifici dell'applicazione per intervalli di tempo.

Stringhe di formato di enumerazione

Vengono descritte le stringhe di formato standard che consentono di creare rappresentazioni di stringa di valori di enumerazione.

Formattazione composta

Viene descritto come incorporare uno o più valori formattati in una stringa, che successivamente può essere visualizzata nella console oppure scritta in un flusso.

Esecuzione di operazioni di formattazione

Sono elencati gli argomenti contenenti istruzioni dettagliate per l'esecuzione di operazioni di formattazione specifiche.

Analisi delle stringhe

Viene descritta l'inizializzazione di oggetti sui valori descritti dalle rappresentazioni in forma di stringa di tali oggetti. L'analisi è l'operazione contraria alla formattazione.

Torna all'inizio

Riferimenti

System.IFormattable

System.IFormatProvider

System.ICustomFormatter