Mise en forme composite

La fonctionnalité de mise en forme composite du .NET utilise une liste d’objets et une chaîne de format composite comme entrée. Une chaîne de format composite comprend à la fois du texte fixe et des espaces réservés indexés appelés éléments de format. Ces éléments de format correspondent aux objets de la liste. L'opération de mise en forme produit une chaîne résultante qui se compose du texte fixe d'origine mélangé à la représentation sous forme de chaîne des objets de la liste.

Important

À la place des chaînes de format composite, vous pouvez utiliser des chaînes interpolées si le type et la version du langage que vous utilisez les prennent en charge. Une chaîne interpolée contient des expressions interpolées. Chaque expression interpolée est résolue avec la valeur de l’expression et incluse dans la chaîne du résultat quand la chaîne est affectée. Pour plus d’informations, consultez Interpolation de chaîne (Informations de référence sur C#) et Chaînes interpolées (Informations de référence sur Visual Basic).

Les méthodes suivantes prennent en charge la fonctionnalité de mise en forme composite :

Chaîne de format composite

Une chaîne de format composite et une liste d'objets sont utilisées comme arguments des méthodes qui prennent en charge la fonctionnalité de mise en forme composite. Une chaîne de format composite est constituée de zéro, une ou plusieurs séquences de texte fixe mélangées à un ou plusieurs éléments de format. Le texte fixe correspond à toute chaîne que vous choisissez, et chaque élément de format correspond à un objet ou une structure boxed dans la liste. La représentation sous forme de chaîne de chaque objet remplace l’élément de format correspondant.

Prenons le fragment de code Format suivant :

string.Format("Name = {0}, hours = {1:hh}", "Fred", DateTime.Now);
String.Format("Name = {0}, hours = {1:hh}", "Fred", DateTime.Now)

Le texte fixe est Name = et , hours = . Les éléments de format sont {0}, dont l’index 0 correspond à l’objet name, et {1:hh}, dont l’index 1 correspond à l’objet DateTime.Now.

Syntaxe des éléments de format

Chaque élément de format prend la forme suivante et comprend les composants suivants :

{index[,alignment][:formatString]}

Les accolades correspondantes ({ et }) sont obligatoires.

Composant index

Le composant obligatoire index, également appelé « spécificateur de paramètre », est un nombre à partir de 0 qui permet d’identifier un élément correspondant dans la liste des objets. Autrement dit, l’élément de format dont le spécificateur de paramètre est 0 met en forme le premier objet de la liste. L’élément de format dont le spécificateur de paramètre est 1 met en forme le deuxième objet de la liste, et ainsi de suite. L’exemple suivant comprend quatre spécificateurs de paramètres, numérotés de 0 à 3, pour représenter les nombres premiers inférieurs à 10 :

string primes = string.Format("Four prime numbers: {0}, {1}, {2}, {3}",
                              2, 3, 5, 7);
Console.WriteLine(primes);

// The example displays the following output:
//      Four prime numbers: 2, 3, 5, 7
Dim primes As String = String.Format("Four prime numbers: {0}, {1}, {2}, {3}",
                                      2, 3, 5, 7)
Console.WriteLine(primes)

'The example displays the following output
'     Four prime numbers 2, 3, 5, 7

Plusieurs éléments de format peuvent faire référence au même élément de la liste d'objets en indiquant le même spécificateur de paramètre. Par exemple, vous pouvez mettre en forme la même valeur numérique au format hexadécimal, scientifique et numérique en spécifiant une chaîne de format composite de type "0x{0:X} {0:E} {0:N}", comme dans cet exemple :

string multiple = string.Format("0x{0:X} {0:E} {0:N}",
                                Int64.MaxValue);
Console.WriteLine(multiple);

// The example displays the following output:
//      0x7FFFFFFFFFFFFFFF 9.223372E+018 9,223,372,036,854,775,807.00
Dim multiple As String = String.Format("0x{0:X} {0:E} {0:N}",
                                       Int64.MaxValue)
Console.WriteLine(multiple)

'The example displays the following output
'     0x7FFFFFFFFFFFFFFF 9.223372E+018 9,223,372,036,854,775,807.00

Chaque élément de format peut faire référence à n'importe quel objet de la liste. Par exemple, si vous avez trois objets à mettre en forme, vous pouvez mettre en forme le deuxième, le premier et le troisième en spécifiant une chaîne de format composite comme {1} {0} {2}. Un objet qui n’est pas référencé par un élément de format est ignoré. Une exception FormatException est levée au moment de l’exécution si un spécificateur de paramètres désigne un élément situé en dehors des limites de la liste d’objets.

Composant alignment

Le composant facultatif alignment est un entier signé indiquant la largeur préférée du champ mis en forme. Si la valeur du composant alignment est inférieure à la longueur de la chaîne mise en forme, alignmentest ignoré, et la longueur de la chaîne mise en forme est utilisée comme largeur de champ. Les données mises en forme dans le champ sont alignées à droite si alignment est positif et alignées à gauche si alignment est négatif. Si un remplissage est nécessaire, des espaces blancs sont utilisés. La virgule est obligatoire si alignment est spécifié.

L’exemple suivant définit deux tableaux, qui contiennent respectivement les noms des employés et leurs heures travaillées sur deux semaines. La chaîne de format composite aligne les noms à gauche dans un champ de 20 caractères et aligne les heures à droite dans un champ de 5 caractères. La chaîne de format standard "N1" met les heures sous la forme d’un nombre avec une décimale.

string[] names = { "Adam", "Bridgette", "Carla", "Daniel",
                   "Ebenezer", "Francine", "George" };
decimal[] hours = { 40, 6.667m, 40.39m, 82,
                    40.333m, 80, 16.75m };

Console.WriteLine("{0,-20} {1,5}\n", "Name", "Hours");

for (int counter = 0; counter < names.Length; counter++)
    Console.WriteLine("{0,-20} {1,5:N1}", names[counter], hours[counter]);

// The example displays the following output:
//      Name                 Hours
//      
//      Adam                  40.0
//      Bridgette              6.7
//      Carla                 40.4
//      Daniel                82.0
//      Ebenezer              40.3
//      Francine              80.0
//      George                16.8
Dim names As String() = {"Adam", "Bridgette", "Carla", "Daniel",
                         "Ebenezer", "Francine", "George"}

Dim hours As Decimal() = {40, 6.667D, 40.39D, 82,
                          40.333D, 80, 16.75D}

Console.WriteLine("{0,-20} {1,5}\n", "Name", "Hours")

For counter = 0 To names.Length - 1
    Console.WriteLine("{0,-20} {1,5:N1}", names(counter), hours(counter))
Next

'The example displays the following output
'     Name                 Hours
'     
'     Adam                  40.0
'     Bridgette              6.7
'     Carla                 40.4
'     Daniel                82.0
'     Ebenezer              40.3
'     Francine              80.0
'     George                16.8

Composant formatString

Le composant facultatif formatString est une chaîne de format appropriée pour le type d’objet mis en forme. Vous pouvez spécifier les valeurs suivantes :

  • Une chaîne de format numérique standard ou personnalisé si l’objet correspondant est une valeur numérique.
  • Une chaîne de format de date et d’heure standard ou personnalisé si l’objet correspondant est un objet DateTime.
  • Une chaîne de format d’énumération si l’objet correspondant est une valeur d’énumération.

Si formatString n’est pas spécifié, le spécificateur de format général ("G") pour un type numérique, de date et d’heure ou d’énumération est utilisé. Le point est obligatoire si formatString est spécifié.

Le tableau suivant répertorie les types ou les catégories de types dans la bibliothèque de classes .NET qui prennent en charge un ensemble prédéfini de chaînes de format. Il fournit aussi des liens vers les articles qui listent les chaînes de format prises en charge. La mise en forme de chaînes est un mécanisme extensible qui permet de définir de nouvelles chaînes de format pour tous les types existants et de définir un ensemble de chaînes de format prises en charge par un type défini par l’application.

Pour plus d’informations, consultez les articles sur les interfaces IFormattable et ICustomFormatter.

Type ou catégorie de type Consultez
Types de date et d'heure (DateTime, DateTimeOffset) Standard Date and Time Format Strings

Custom Date and Time Format Strings
Types d'énumération (tous les types dérivés de System.Enum) Enumeration Format Strings
Types numériques (BigInteger, Byte, Decimal, Double, Int16, Int32, Int64, SByte, Single, UInt16, UInt32, UInt64) Chaînes de format numériques standard

Custom Numeric Format Strings
Guid Guid.ToString(String)
TimeSpan Chaînes de format TimeSpan standard

Chaînes de format TimeSpan personnalisées

Accolades d’échappement

Les accolades ouvrantes et fermantes sont interprétées comme le début et la fin d'un élément de format. Pour afficher une accolade ouvrante ou fermante littérale, vous devez utiliser une séquence d’échappement. Spécifiez deux accolades ouvrantes ({{) dans le texte fixe pour afficher une accolade ouvrante ({), ou deux accolades fermantes (}}) pour afficher une accolade fermante (}).

Les accolades échappées avec un élément de format sont analysées différemment entre .NET et .NET Framework.

.NET

Les accolades peuvent être échappées autour d’un élément de format. Prenons l’exemple de l’élément de format {{{0:D}}}, qui devrait afficher une accolade ouvrante, une valeur numérique sous forme de nombre décimal et une accolade fermante. L’élément de format est interprété de la manière suivante :

  1. Les deux premières accolades ouvrantes ({{) sont interprétées comme une séquence d’échappement et se traduisent par une seule accolade ouvrante affichée.
  2. Les trois caractères suivants ({0:) sont interprétés comme le début d’un élément de format.
  3. Le caractère suivant (D) est interprété comme spécificateur de format numérique standard décimal.
  4. L’accolade suivante (}) est interprétée comme la fin de l'élément de format.
  5. Les deux dernières accolades fermante sont échappées et donnent une accolade fermante.
  6. Le résultat final affiché est la chaîne littérale, {6324}.
int value = 6324;
string output = string.Format("{{{0:D}}}", value);

Console.WriteLine(output);
// The example displays the following output:
//       {6324}
Dim value As Integer = 6324
Dim output As String = String.Format("{{{0:D}}}", value)

Console.WriteLine(output)

'The example displays the following output
'      {6324}

.NET Framework

Les accolades dans un élément de format sont interprétées séquentiellement dans l’ordre dans lequel elles sont rencontrées. L’interprétation des accolades imbriquées n’est pas prise en charge.

La façon dont les accolades d'échappement sont interprétées peut générer des résultats inattendus. Prenons l’exemple de l’élément de format {{{0:D}}}, qui devrait afficher une accolade ouvrante, une valeur numérique sous forme de nombre décimal et une accolade fermante. En réalité, l’élément de format est interprété de la manière suivante :

  1. Les deux premières accolades ouvrantes ({{) sont interprétées comme une séquence d’échappement et se traduisent par une seule accolade ouvrante affichée.
  2. Les trois caractères suivants ({0:) sont interprétés comme le début d’un élément de format.
  3. Le caractère suivant (D) devrait être interprété comme le spécificateur de format numérique décimal standard, mais les deux accolades d’échappement qui suivent (}}) produisent une seule accolade. Comme la chaîne résultante (D}) n’est pas un spécificateur de format numérique standard, elle est interprétée comme une chaîne de format personnalisé qui sous-entend l’affichage de la chaîne littérale D}.
  4. La dernière accolade (}) est interprétée comme la fin de l’élément de format.
  5. Le résultat final affiché est la chaîne littérale, {D}. La valeur numérique qui devait être mise en forme n’est pas affichée.
int value = 6324;
string output = string.Format("{{{0:D}}}",
                              value);
Console.WriteLine(output);

// The example displays the following output:
//       {D}
Dim value As Integer = 6324
Dim output As String = String.Format("{{{0:D}}}",
                                     value)
Console.WriteLine(output)

'The example displays the following output:
'      {D}

Pour éviter une mauvaise interprétation des accolades d’échappement et des éléments de format, mettez-les en forme séparément les uns des autres dans votre code. Plus précisément, la première opération de mise en forme doit afficher une accolade ouvrante littérale. L’opération suivante doit afficher le résultat de l’élément de format, et l’opération finale doit afficher une accolade fermante littérale. L'exemple suivant illustre cette approche :

int value = 6324;
string output = string.Format("{0}{1:D}{2}",
                             "{", value, "}");
Console.WriteLine(output);

// The example displays the following output:
//       {6324}
Dim value As Integer = 6324
Dim output As String = String.Format("{0}{1:D}{2}",
                                     "{", value, "}")
Console.WriteLine(output)

'The example displays the following output:
'      {6324}

Ordre de traitement

Si l’appel de la méthode de mise en forme composite comprend un argument IFormatProvider dont la valeur n’est pas null, le runtime appelle sa méthode IFormatProvider.GetFormat pour demander une implémentation de ICustomFormatter. Si la méthode peut retourner une implémentation de ICustomFormatter, elle est mise en cache pendant l’appel de la méthode de mise en forme composite.

Chaque valeur de la liste de paramètres qui correspond à un élément de mise en forme est convertie en une chaîne de la manière suivante :

  1. Si la valeur à mettre en forme est null, une chaîne vide String.Empty est retournée.

  2. Si une implémentation de ICustomFormatter est disponible, le runtime appelle sa méthode Format. Le runtime passe la valeur formatString de l’élément de format (ou null à défaut) à la méthode. Le runtime passe également l’implémentation de IFormatProvider à la méthode. Si l’appel de la méthode ICustomFormatter.Format retourne null, l’exécution se poursuit à l’étape suivante. Sinon, le résultat de l’appel de ICustomFormatter.Format est retourné.

  3. Si la valeur implémente l'interface IFormattable, la méthode de l'interface ToString(String, IFormatProvider) est appelée. Si l’élément de format en contient une, la valeur formatString est passée à la méthode. À défaut, la valeur null est passée. L'argument IFormatProvider est déterminé comme suit :

  4. La méthode ToString sans paramètre du type, qui remplace Object.ToString() ou hérite du comportement de la classe de base, est appelée. Dans ce cas, la chaîne de format spécifiée par le composant formatString dans l’élément de format, si elle est présente, est ignorée.

L'alignement est appliqué une fois les précédentes étapes effectuées.

Exemples de code

L'exemple suivant illustre une chaîne créée à l'aide de la mise en forme composite et une autre chaîne créée à l'aide de la méthode ToString d'un objet. Les deux types de mise en forme produisent des résultats équivalents.

string formatString1 = string.Format("{0:dddd MMMM}", DateTime.Now);
string formatString2 = DateTime.Now.ToString("dddd MMMM");
Dim formatString1 As String = String.Format("{0:dddd MMMM}", DateTime.Now)
Dim formatString2 As String = DateTime.Now.ToString("dddd MMMM")

En supposant que le jour actuel soit un jeudi du mois de mai, la valeur des deux chaînes de l'exemple précédent est Thursday May dans la culture américaine.

Console.WriteLine présente les mêmes fonctionnalités que String.Format. La seule différence entre les deux méthodes est que String.Format retourne son résultat sous la forme d'une chaîne, alors que Console.WriteLine écrit le résultat dans le flux de sortie associé à l'objet Console. L’exemple suivant utilise la méthode Console.WriteLine pour mettre en forme la valeur de myNumber en valeur monétaire :

int myNumber = 100;
Console.WriteLine("{0:C}", myNumber);

// The example displays the following output
// if en-US is the current culture:
//        $100.00
Dim myNumber As Integer = 100
Console.WriteLine("{0:C}", myNumber)

'The example displays the following output
'if en-US Is the current culture:
'       $100.00

L’exemple suivant illustre la mise en forme de plusieurs objets, y compris la mise en forme d’un objet de deux façons différentes :

string myName = "Fred";
Console.WriteLine(string.Format("Name = {0}, hours = {1:hh}, minutes = {1:mm}",
                                myName, DateTime.Now));

// Depending on the current time, the example displays output like the following:
//        Name = Fred, hours = 11, minutes = 30
Dim myName As String = "Fred"
Console.WriteLine(String.Format("Name = {0}, hours = {1:hh}, minutes = {1:mm}",
                                myName, DateTime.Now))
'Depending on the current time, the example displays output Like the following:
'       Name = Fred, hours = 11, minutes = 30

L'exemple suivant illustre l'utilisation de l'alignement lors de la mise en forme. Les arguments mis en forme sont placés entre des barres verticales (|) pour mettre en évidence l’alignement en résultant.

string firstName = "Fred";
string lastName = "Opals";
int myNumber = 100;

string formatFirstName = string.Format("First Name = |{0,10}|", firstName);
string formatLastName = string.Format("Last Name =  |{0,10}|", lastName);
string formatPrice = string.Format("Price =      |{0,10:C}|", myNumber);
Console.WriteLine(formatFirstName);
Console.WriteLine(formatLastName);
Console.WriteLine(formatPrice);
Console.WriteLine();

formatFirstName = string.Format("First Name = |{0,-10}|", firstName);
formatLastName = string.Format("Last Name =  |{0,-10}|", lastName);
formatPrice = string.Format("Price =      |{0,-10:C}|", myNumber);
Console.WriteLine(formatFirstName);
Console.WriteLine(formatLastName);
Console.WriteLine(formatPrice);

// The example displays the following output on a system whose current
// culture is en-US:
//     First Name = |      Fred|
//     Last Name =  |     Opals|
//     Price =      |   $100.00|
//
//     First Name = |Fred      |
//     Last Name =  |Opals     |
//     Price =      |$100.00   |
Dim firstName As String = "Fred"
Dim lastName As String = "Opals"
Dim myNumber As Integer = 100

Dim formatFirstName As String = String.Format("First Name = |{0,10}|", firstName)
Dim formatLastName As String = String.Format("Last Name =  |{0,10}|", lastName)
Dim formatPrice As String = String.Format("Price =      |{0,10:C}|", myNumber)
Console.WriteLine(formatFirstName)
Console.WriteLine(formatLastName)
Console.WriteLine(formatPrice)
Console.WriteLine()

formatFirstName = String.Format("First Name = |{0,-10}|", firstName)
formatLastName = String.Format("Last Name =  |{0,-10}|", lastName)
formatPrice = String.Format("Price =      |{0,-10:C}|", myNumber)
Console.WriteLine(formatFirstName)
Console.WriteLine(formatLastName)
Console.WriteLine(formatPrice)

'The example displays the following output on a system whose current
'culture Is en-US:
'    First Name = |      Fred|
'    Last Name =  |     Opals|
'    Price =      |   $100.00|
'
'    First Name = |Fred      |
'    Last Name =  |Opals     |
'    Price =      |$100.00   |

Voir aussi