string.format avec variables vs variables en ligne

9

Quels sont les avantages / inconvénients (le cas échéant) de l'utilisation

string output; 
int i = 10;
output = string.Format("the int is {0}", i);

contre

string output; 
int i = 10;
output = "the int is " + i;

J'ai toujours utilisé ce dernier exemple, mais il semble que la bonne majorité des didacticiels en ligne utilisent l'exemple string.format. Je ne pense pas qu'il y ait de réelles différences en termes d'efficacité, ma pensée initiale est donc qu'un codeur n'a pas à continuer de casser la chaîne pour insérer des variables.

Jim
la source
8
La raison principale est que cela rend la traduction beaucoup plus facile, car votre programme n'a pas besoin de comprendre comment les différentes langues construisent leurs phrases. Par exemple, de nombreuses expressions et expressions en français sont recto verso par rapport à leurs traductions en anglais.
JohnL

Réponses:

22

Si vous considérez que la traduction est importante dans votre projet, la première syntaxe vous aidera vraiment.

Par exemple, vous pouvez avoir:

static final string output_en = "{0} is {1} years old.";
static final string output_fr = "{0} a {1} ans.";

int age = 10;
string name = "Henri";
System.out.println(string.Format(output_en, name, age));
System.out.println(string.Format(output_fr, name, age));

Notez également que vos variables peuvent ne pas toujours être au même endroit dans la phrase avec cette syntaxe:

static final string output_yoda = "{1} years {0} has.";
Alex Garcia
la source
4
+1 pour l'utilisation de Yoda-speak comme exemple de syntaxe objet-sujet-verbe.
Mike Harris
1
Avec C # nous avons une nouvelle option:System.out.println($"{name} is {age} year's old.");
Berin Loritsch
@BerinLoritsch: qui est complètement inutilisable pour la localisation, malheureusement.
Bryan Boettcher
@BryanBoettcher, compris, mais je n'ai rien vu dans l'OP disant que c'est ce qu'ils essayaient d'accomplir.
Berin Loritsch
8

Consultez la première réponse pour /programming/4671610/why-use-string-format . Il couvre tout à mon avis pour savoir pourquoi c'est mieux.

En outre, chaque assembly .NET possède un pool interne, contenant une collection de chaînes uniques. Lorsque votre code est compilé, tous les littéraux de chaîne auxquels vous faites référence dans votre code sont ajoutés à ce pool. Si vous avez un code qui ressemble à ceci:

"the int is " + i + " and the double is " + d

Cela fait 2 cordes dans la piscine.

Si tu as:

"the int is {0} and the double is {1}"

Vous n'avez qu'une seule chaîne dans le pool.

Il est un peu plus compliqué de savoir quand les chaînes sont internées, et quand elles ne le sont pas parce que le compilateur a une certaine intelligence lors de la détection de chaînes qui peuvent ne pas avoir besoin d'être internées parfois ... Consultez par exemple cet article qui donne plus d'informations sur ce sujet. matière.

Edit: après avoir creusé un peu, j'ai rencontré une réponse intéressante à la question Quand est-il préférable d'utiliser String.Format vs la concaténation de chaînes? . En bref, l'auteur de la réponse avec +30 votes fait un argument convaincant en faveur de la concaténation de chaînes lorsque la localisation n'est pas impliquée.

Jalayn
la source
2
Je pense aussi, stylistiquement, que cela résonne avec les gens, c'est-à-dire les gens comme moi, qui ont l'habitude d'imprimer et de sprinter à partir de c.
Jonathan Henson
J'aurais aimé savoir pourquoi le downvote afin de fixer ma réponse. Merci.
Jalayn
4

Je préfère la première façon, car elle me permet de voir avec précision à quoi ressemblera la chaîne lors de la sortie. Il est très facile d'oublier d'ajouter un espace ou d'ajouter un espacement supplémentaire lorsque vous ajoutez simplement des chaînes.

Je suis sûr qu'il y a aussi un avantage en termes de performances à la première façon car il n'est pas nécessaire de créer les chaînes supplémentaires; mais ce n'est pas ma principale préoccupation.

John Kraft
la source
2

En utilisant la première option, vous pouvez stocker une chaîne de format couramment utilisée et réduire la saisie nécessaire et faciliter la mise à jour de la chaîne partout où elle est utilisée. Fondamentalement, la première option permet d'implémenter facilement DRY. C'est également une syntaxe beaucoup plus agréable si plusieurs variables doivent être utilisées dans une chaîne, comme vous l'avez mentionné.

Ryathal
la source
ahh je vois, je suppose que je n'ai pas pensé à l'exemple: string.format ("l'int est {0}. encore c'est {0}", int);
Jim
1

Je pense qu'avec string.Format()c'est plus facile de voir quel sera exactement le résultat (donc vous n'avez pas de problèmes avec des espaces oubliés ou quelque chose comme ça), et c'est aussi plus facile à taper et à modifier.

Si vous voulez faire un formatage très simple, utiliser l' +opérateur plus peut être plus facile, mais j'ai tendance à ne l'utiliser que lors de la concaténation de deux chaînes, pas plus.

Pour montrer comment il string.Format()est plus facile de modifier, considérez que vous vouliez ajouter un point à la fin de la phrase dans votre exemple: passer de string.Format("The int is {0}", i)à string.Format("The int is {0}.", i)n'est qu'un caractère. Mais passer de "the int is " + ià "the int is " + i + '.'est beaucoup plus.

Un autre avantage string.Format()est qu'il vous permet de spécifier facilement le format à utiliser, comme string.Format("The int is 0x{0:X}.", i). Ceci est encore plus important lors du formatage de la date.

Quant à l'efficacité, elle string.Format()est très probablement plus lente que les concaténations de chaînes simples. Mais un code comme celui-ci n'est probablement pas sur un chemin chaud, donc cela n'a pas d'importance. Et si c'est le cas, il vaut probablement mieux utiliser StringBuilder.

svick
la source
string.Format utilise de toute façon un StringBuilder
Bryan Boettcher
1

Utilisez celui qui rend votre code le plus lisible. Ne vous inquiétez pas des performances.

Pour votre exemple ci-dessous, je préfère B car il est juste plus lisible. Mais les traductions linguistiques ci-dessus ont également un sens. Ne laissez personne vous forcer à utiliser de la chaîne.Formatez, au lieu de cela, lisez et pointez vers l'excellent blog de Jeff Atwoods sur la triste tragédie des micro-optimisations.

UNE:

string output; 
int i = 10;
output = string.Format("the int is {0}", i);

contre

B:

string output; 
int i = 10;
output = "the int is " + i;
Makach
la source
-1

Réf: Sortie chaîne: format ou concat en C #?

Considérez ce code.

C'est une version légèrement modifiée de votre code.

  1. J'ai supprimé Console.WriteLine car il est probablement quelques ordres de grandeur plus lent que ce que j'essaie de mesurer.
  2. Je regarde le chronomètre avant la boucle et je l'arrête juste après, de cette façon je ne perds pas de précision si la fonction prend par exemple 26,4 ticks pour s'exécuter.
  3. La façon dont vous avez divisé le résultat en nombre d'itérations était incorrecte. Voyez ce qui se passe si vous avez 1000 millisecondes et 100 millisecondes. Dans les deux cas, vous obtiendrez 0 ms après l'avoir divisé par 1000000.
Stopwatch s = new Stopwatch();

var p = new { FirstName = "Bill", LastName = "Gates" };

int n = 1000000;
long fElapsedMilliseconds = 0, fElapsedTicks = 0, cElapsedMilliseconds = 0, cElapsedTicks = 0;

string result;
s.Start();
for (var i = 0; i < n; i++)
    result = (p.FirstName + " " + p.LastName);
s.Stop();
cElapsedMilliseconds = s.ElapsedMilliseconds;
cElapsedTicks = s.ElapsedTicks;
s.Reset();
s.Start();
for (var i = 0; i < n; i++)
    result = string.Format("{0} {1}", p.FirstName, p.LastName);
s.Stop();
fElapsedMilliseconds = s.ElapsedMilliseconds;
fElapsedTicks = s.ElapsedTicks;
s.Reset();


Console.Clear();
Console.WriteLine(n.ToString()+" x result = string.Format(\"{0} {1}\", p.FirstName, p.LastName); took: " + (fElapsedMilliseconds) + "ms - " + (fElapsedTicks) + " ticks");
Console.WriteLine(n.ToString() + " x result = (p.FirstName + \" \" + p.LastName); took: " + (cElapsedMilliseconds) + "ms - " + (cElapsedTicks) + " ticks");
Thread.Sleep(4000);

Ce sont mes résultats:

1000000 x result = string.Format("{0} {1}", p.FirstName, p.LastName); took: 618ms - 2213706 ticks
1000000 x result = (p.FirstName + " " + p.LastName); took: 166ms - 595610 ticks
jp2code
la source
1
Comment cela répond-il aux aspects si le premier exemple de code ou le deuxième exemple de code est une meilleure conception? Comment une demi-seconde sur 1M d'itérations explique-t-elle si c'est un code plus facile à maintenir pour une personne ou non?
Jim a demandé: "Quels sont les avantages et les inconvénients?" Cela montre que sur de nombreuses itérations, String.Format est plus rapide.
jp2code
Vous devriez envisager d'ajouter pleinement cela à votre réponse plutôt que de le laisser comme un bloc de code et des différences par rapport au code de l'OP. En l'état, votre réponse ne répond pas à la question du PO en anglais. Regardez les autres réponses. Il serait possible de leur retirer tout le code et d'avoir toujours une réponse à la question du PO.