Condividi tramite


Personalizzazione di stringhe di formato

Aggiornamento: novembre 2007

.NET Framework supporta l'estensione del meccanismo di formattazione incorporato che consente di creare un metodo ToString personalizzato in grado di accettare stringhe di formato definite dall'utente oppure un provider di formato con cui viene richiamato un metodo Format personalizzato per eseguire la formattazione personalizzata di un tipo. Il metodo ToString viene creato mediante l'implementazione dell'interfaccia IFormattable, mentre il metodo Format viene creato mediante l'implementazione delle interfacce ICustomFormatter e IFormatProvider.

Le informazioni fornite in questa sezione illustrano solo l'aggiunta di stringhe di formato personalizzato a tipi definiti dall'utente e a tipi di base esistenti, tuttavia i principi descritti possono essere applicati a qualsiasi tipo.

Aggiunta di stringhe di formato personalizzato per tipi personalizzati

In caso di creazione di un tipo personalizzato, è possibile aggiungere il supporto per l'elaborazione di stringhe di formato personalizzato implementando l'interfaccia IFormattable e il relativo metodo ToString. È così possibile controllare le stringhe di formato riconosciute dal tipo personalizzato. Il vantaggio offerto dall'implementazione dell'interfaccia IFormattable rispetto alla semplice aggiunta di un metodo ToString al tipo personalizzato consiste nel fatto che è possibile garantire agli utenti del metodo ToString una sintassi di chiamata e un tipo restituito predefiniti.

Il metodo ToString dell'interfaccia IFormattable accetta un parametro costituito da una stringa di formato e un parametro costituito da un provider di formato. Se il parametro della stringa di formato è una stringa vuota o null (Nothing in Visual Basic), eseguire la formattazione predefinita. Se il provider di formato è null, utilizzare un provider di formato predefinito.

Se alla versione personalizzata di null viene passata una stringa di formato personalizzato, eseguire la formattazione appropriata. In caso contrario, chiamare un metodo .NET Framework adeguato per eseguire la formattazione standard.

Nell'esempio riportato di seguito il tipo personalizzato MyType implementa l'interfaccia IFormattable. Se si crea una nuova istanza della classe MyType e si passa la stringa di formato personalizzato "b" al metodo ToString dell'istanza, un overload di Convert.ToString restituirà la rappresentazione di stringa binaria (in base 2) del valore dell'istanza. Se non si passa "b", il valore dell'istanza verrà formattato mediante il relativo metodo ToString. Il valore integer myValue verrà quindi formattato mediante il metodo System.Int32.ToString.

Public Class MyType
    Implements IFormattable
    ' Assign a value for the class.
    Private myValue As Integer    

    ' Add a constructor.
    Public Sub New(value As Integer)
        myValue = value
    End Sub

    ' Write a custom Format method for the type.
    Public Overloads Function ToString(format As String, _
                                       fp As IFormatProvider) As String _
                              Implements IFormattable.ToString

        If format.Equals("b") Then
            Return Convert.ToString(myValue, 2)
        Else
            Return myValue.ToString(format, fp)
        End If
    End Function
End Class
public class MyType : IFormattable
{
    // Assign a value for the class.
    private int myValue;

    // Add a constructor.
    public MyType( int value )
    {
        myValue = value;
    }
    // Write a custom Format method for the type.
    public string ToString(string format, IFormatProvider fp)
    {
        if (format.Equals ("b"))
            {
            return Convert.ToString (myValue, 2);
            }
        else
            {
            return myValue.ToString(format, fp);
            }
    }
}

Nell'esempio riportato di seguito viene illustrato l'utilizzo della classe MyType e della stringa di formato "b".

Dim mtype As New MyType(42)
Dim myString As String = mtype.ToString("b", Nothing)
Dim yourString As String = mtype.ToString("d", Nothing)
Console.WriteLine(myString)
Console.WriteLine(yourString)
' The example produces the following output:
'       101010
'       42
MyType mtype = new MyType(42);
String myString = mtype.ToString("b", null);
String yourString = mtype.ToString("d", null);
Console.WriteLine(myString);
Console.WriteLine(yourString);
// The example produces the following output:
//       101010
//       42

Aggiunta di stringhe di formato personalizzato a tipi esistenti

È possibile controllare la modalità di formattazione di un tipo di base e fornire codici aggiuntivi per la formattazione creando una classe di provider di formato che implementa ICustomFormatter e IFormatProvider.

Quando si passa un provider di formato al metodo System.Int32.ToString di un tipo di base, il tipo di base utilizza il provider di formato passato per definire specifiche regole di formattazione in sostituzione del provider di formato predefinito. Per creare un provider di formato personalizzato è preferibile attenersi alla procedura illustrata di seguito.

  1. Definire una classe che implementi le due interfacce citate in precedenza e che esegua l'override di GetFormat e Format.

  2. Passare tale classe in un metodo, quale String.Format, che accetti IFormatProvider come parametro. Questo fa sì che String.Format riconosca lo schema di formato personalizzato definito nella nuova classe di provider di formato.

Nell'esempio riportato di seguito viene definita una classe che aggiunge un metodo Format personalizzato in grado di produrre diversi valori di base di un valore integer.

Public Class MyFormat
    Implements IFormatProvider
    Implements ICustomFormatter

    ' String.Format calls this method to get an instance of an
    ' ICustomFormatter to handle the formatting.
    Public Function GetFormat(service As Type) As Object _
    Implements IFormatProvider.GetFormat

        If service.ToString() = GetType(ICustomFormatter).ToString() Then
            Return Me
        Else
            Return Nothing
        End If
    End Function

    ' After String.Format gets the ICustomFormatter, it calls this format
    ' method on each argument.
    Public Function Format(theformat As String, arg As Object, _
                           provider As IFormatProvider) As String _
                    Implements ICustomFormatter.Format

        If theformat Is Nothing Then
            Return String.Format("{0}", arg)
        End If
        Dim i As Integer = theformat.Length
            ' If the object to be formatted supports the IFormattable
            ' interface, pass the format specifier to the 
            ' objects ToString method for formatting.
        If Not theformat.StartsWith("B") Then
            ' If the object to be formatted supports the IFormattable
            ' interface, pass the format specifier to the 
            ' objects ToString method for formatting.
            If TypeOf arg Is IFormattable Then
                return CType(arg, IFormattable).ToString(theformat, provider)
            ' If the object does not support IFormattable, 
            ' call the objects ToString method with no additional
            ' formatting. 
            ElseIf (arg Is Nothing) Then
                return arg.ToString()
            End If
        End If
        ' Uses the format string to
        ' form the output string.
        theformat = theformat.Trim(New Char() {"B"c})
        Dim b As Integer = Convert.ToInt32(theformat)
        Return Convert.ToString(CInt(arg), b)
    End Function
End Class
public class MyFormat : IFormatProvider, ICustomFormatter
{
    // String.Format calls this method to get an instance of an
    // ICustomFormatter to handle the formatting.
    public object GetFormat (Type service)
    {
        if (service == typeof (ICustomFormatter))
        {
            return this;
        }
        else
        {
            return null;
        }
    }
    // After String.Format gets the ICustomFormatter, it calls this format
    // method on each argument.
    public string Format(string format, object arg, IFormatProvider provider) 
    {
        if (format == null)
        {
            return String.Format ("{0}", arg);
        }
        // If the format is not a defined custom code,
        // use the formatting support in ToString.
        if (!format.StartsWith("B")) 
        {
            //If the object to be formatted supports the IFormattable
            //interface, pass the format specifier to the 
            //objects ToString method for formatting.
            if (arg is IFormattable) 
            {
                return ((IFormattable)arg).ToString(format, provider);
            } 
            //If the object does not support IFormattable, 
            //call the objects ToString method with no additional
            //formatting. 
            else if (arg != null) 
            {
                return arg.ToString();
            }
        }
        // Uses the format string to
        // form the output string.
        format = format.Trim (new char [] {'B'});
        int b = Convert.ToInt32 (format);
        return Convert.ToString ((int)arg, b);
    }
}

Nell'esempio riportato di seguito, il metodo Format utilizza il metodo Format personalizzato, definito in MyFormat, per visualizzare la rappresentazione a base 16 di MyInt.

Dim myInt As Integer = 42
Dim myString As String = String.Format(New MyFormat(), _
                         "{0} in the custom B16 format is {1:B16}", _
                         New Object() {MyInt, MyInt})
Console.WriteLine(myString)
' The example displays the following output:
'      42 in the custom B16 format is 2a
int MyInt = 42;
string myString = String.Format(new MyFormat(), 
                         "{0} in the custom B16 format is {1:B16}", 
                         new object[] {MyInt, MyInt});
Console.WriteLine(myString);                               
// The example displays the following output: 
//       42 in custom B16 format is 2a

Vedere anche

Riferimenti

IFormattable

IFormatProvider

ICustomFormatter

Altre risorse

Formattazione dei tipi di dati