Personnalisation des chaînes de format
Mise à jour : novembre 2007
Le .NET Framework prend en charge l'extension de son mécanisme de mise en forme intégré de sorte que vous puissiez créer votre propre méthode ToString qui accepte des chaînes de format définies par l'utilisateur ou créer un fournisseur de format qui appelle votre propre méthode Format pour effectuer une mise en forme personnalisée d'un type. Vous créez votre propre méthode ToString en implémentant l'interface IFormattable et votre propre méthode Format en implémentant les interfaces ICustomFormatter et IFormatProvider.
Les informations contenues dans cette section se limitent à l'ajout de chaînes de format personnalisées à des types définis par l'utilisateur et à des types de base existants, mais les principes décrits peuvent être appliqués à n'importe quel type.
Ajout de chaînes de format personnalisées pour des types personnalisés
Si vous créez votre propre type personnalisé, vous pouvez ajouter une prise en charge pour le traitement de vos chaînes de format personnalisées en implémentant l'interface IFormattable et la méthode ToString de cette interface. Cela signifie que vous pouvez contrôler quelles chaînes de format sont reconnues par votre type personnalisé. L'avantage de l'implémentation de l'interface IFormattable par rapport au simple ajout d'une méthode ToString à votre type personnalisé est que vous pouvez garantir aux utilisateurs de votre méthode ToString une syntaxe d'appel et un type de retour prédéfinis.
La méthode ToString de l'interface IFormattable prend un paramètre de chaîne de format et un paramètre de fournisseur de format. Si le paramètre de chaîne de format est une chaîne vide ou null (Nothing en Visual Basic), effectuez la mise en forme par défaut. Si le fournisseur de format est null, utilisez un fournisseur de format par défaut.
Si une chaîne de format personnalisée est passée à votre version personnalisée de ToString, effectuez la mise en forme appropriée ; sinon, appelez une méthode .NET Framework appropriée pour effectuer une mise en forme standard.
Dans l'exemple suivant, le type personnalisé MyType implémente l'interface IFormattable. Si vous créez une nouvelle instance de la classe MyType et passez la chaîne de format personnalisée « b » à la méthode ToString de l'instance, une surcharge de Convert.ToString retourne la représentation binaire sous forme de chaîne (base 2) de la valeur de l'instance. Si « b » n'est pas passé, la valeur de l'instance est mise en forme par sa propre méthode ToString ; cela signifie que l'entier myValue est mis en forme par la méthode 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);
}
}
}
L'exemple suivant illustre comment la classe MyType et la chaîne de format « b » sont utilisées.
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
Ajout de chaînes de format personnalisées à des types existants
Vous pouvez contrôler comment un type de base existant est mis en forme et fournir du code complémentaire pour la mise en forme en créant une classe de fournisseur de format qui implémente ICustomFormatter et IFormatProvider.
Si vous passez un fournisseur de format à la méthode ToString d'un type de base, ce dernier utilise le fournisseur de format passé plutôt que le fournisseur de format par défaut pour définir ses règles de mise en forme. Pour créer un fournisseur de format personnalisé, procédez de la manière suivante :
Définissez une classe qui implémente les deux interfaces mentionnées précédemment et substitue GetFormat et Format.
Passez cette classe dans une méthode (telle que String.Format) qui prend IFormatProvider comme paramètre. De cette manière, String.Format reconnaît le modèle de format personnalisé défini dans la nouvelle classe de fournisseur de format.
L'exemple suivant définit une classe qui ajoute une méthode Format personnalisée pouvant produire différentes valeurs de base d'un entier.
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);
}
}
Dans l'exemple suivant, la méthode Format utilise la méthode personnalisée Format définie dans MyFormat pour afficher la représentation en base 16 de 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