7. String Interpolation en C#, concaténer des chaînes
La “String Interpolation” est un moyen d’entrer des valeurs à l’intérieur de chaînes qui rendent le code extrêmement lisible. Les chaînes interpolées ont été introduites à partir de la version 6 de C# avec l’intention de «simplifier», de «condenser», mais surtout de «clarifier» l’intention du code.
Avant d’examiner la String Interpolation, il est utile de revoir les méthodes de concaténation des chaînes attendues en C# avant la version 6 :
- le plus puissant StringBuilder;
- concaténation via l’opérateur +;
- string.Format qui est un peu la synthèse des deux méthodes. Pour compléter le tout, il faudrait aussi voir la méthode AppendFormat de StringBuilder, que nous pouvons le considérer dans le string.Format.
StringBuilder
StringBuilder est la méthode la plus puissante en termes de mémoire, mais elle n’est pas le summum de la simplification et de la lecture.
using System;
using System.Text;
using Xunit;
namespace StringInterpolation
{
public class Obj
{
public Obj(int id, string valeur, DateTime cree)
{
Id = id;
Valeur = valeur;
Cree = cree;
}
public int Id { get; set; }
public stringValeur { get; set; }
public DateTime Cree { get; set; }
}
public class Test
{
private const string ValeurAttendue = "Bonjour je suis un objet avec Id:1, Valeur:'Ok' et créé avec 20171105";
private const string ValeurAttendueConditionnel = "Bonjour je suis un objet avec Id:1, Valeur:'Ok' et créé le 20171105 donc actuel";
private readonly Obj _obj = new Obj(1,"Ok", DateTime.Parse("2017 - 11 - 05 00: 00:00"));
[Fact]
public void StringBuilderTest()
{
var sb = new StringBuilder();
sb.Append("Bonjour je suis un objet avec Id:");
sb.Append(_obj.Id);
sb.Append(", Valeur:'");
sb.Append(_obj.Valeur);
sb.Append("' et créé le ");
sb.Append(_obj.Cree.ToString("yyyyMMdd"));
var chaine = sb.ToString();
Assert.Equal(ValeurAttendue, chaine);
}
}
}
Concaténation avec l’opérateur “+”
Juste pour la complexité des autres méthodes, de nombreux programmeurs utilisent la concaténation par avec l’opérateur +.
[Fact] public void EnchainementTest() { var chaine = "Bonjour je suis un objet avec Id :" + _obj.Id + ", Valeur:'" + _obj.Valeur + "' et créé le " + _obj.Cree.ToString("yyyyMMdd"); Assert.Equal(ValeurAttendue, chaine); }
Il est évident que cette façon de faire est plus lisible, mais la concaténation n’est pas performante pas parce que chaque l’objet est combiné avec deux objets copiés dans un nouvel objet chaîne, ce qui entraîne une prolifération d’objets en mémoire.
Ce n’est pas bon pour la mémoire et surtout cette façon de faire n’est pas performante.
string.Format
string.Format combine les deux exigences précédentes avec un petit compromis. Il utilise string.builder et en particulier la méthode appendformat avec un léger overhead, tout en conservant de bonnes performances de la mémoire.
[Fact] public void StringFormatTest() { var chaine = string.Format( "Bonjour je suis un objet avec Id:{0}, Valeur:'{1}' et créé le {2:yyyyMMdd}", _obj.Id, _obj.Valeur, _obj.Cree); Assert.Equal(ValeurAttendue, chaine); }
Cependant, avec trois paramètres, la lecture peut ne pas être immédiate, puisque la recherche de chaque paramètre trouvé dans la chaîne doit sauter à la valeur associée pour comprendre ce qui va y être écrit. Ce problème est encore plus grand si l’ordre des paramètres n’est pas linéaire (provoquer l’évolution du code).
String Interpolation
Pour répondre au besoin de maintenance, il y a les chaînes interpolées (string interpolation) qui évoluent autant que le string.Format dans une méthode encore plus simple et condensée. Voici un exemple :
var chaine = $"Bonjour {nom_user}, comment vas-tu ?";
La syntaxe est :
$" <texte> { <expression> [,<largeur-a-respecter>] [:<format>] } <texte> {... } "
Argument | Description |
---|---|
texte | C’est le texte qui précède ou suit les valeurs interpolées. |
expression | C’est l’expression qui retournera la valeur à insérer dans la chaîne. |
largeur-a-respecter | [optionnel] nombre de caractères. Il sert si nous voulons que la partie interpolée de chaîne ressemble à une certaine taille, des espaces sont ajoutés quand la taille désirée n’est pas atteinte. |
format | [Facultatif] est utilisé pour introduire un format à la valeur calculée. Par exemple, pour avoir seulement les deux premières décimales d’un nombre, nous ajoutons :F2 . |
Il est préférable de l’utiliser car cette méthode réduit les erreurs typiques qui sont commises avec la méthode string.Format, comme le mauvais ordre des arguments ou l’absence d’un ou plusieurs paramètres.
[Fact] public void StringInterpolationTest() { var chaine = $"Bonjour je suis un objet avec Id:{_obj.Id}, Valeur'{_obj.Valeur}' et créé le {_obj.Cree:yyyyMMdd}"; Assert.Equal(ValeurAttendue, chaine); }
La string interpolation permet également de condenser le code conditionnel :
[Fact]
public void StringInterpolationPlusTest()
{
var chaine = $"Bonjour je suis un objet avec Id:{_obj.Id}, Valeur:'{_obj.Valeur}' et créé le {_obj.Cree:yyyyMMdd}{(_obj.Cree.Year>=2017?" donc actuel" : "")}";
Assert.Equal(ValeurAttendueConditionnel, chaine);
}
En fait, string interpolation est modifiée à compile time qui équivaut à un string.Format, donc ce n’est pas une fonctionnalité du framework, mais du langage, et donc liée à la version d’IDE (Visual Studio 2017) et non une version particulière du framework. Vous devez donc faire attention en équipes où certains ont la version 2015 et d’autres 2017.
Précédent : 6. Types de données de base et passage de paramètres Suivant : 8. Héritage
Étiquette :chaînes, Interpolation, String, Structure du langage