web-dev-qa-db-fra.com

Pourquoi utiliser String.Format?

Pourquoi quelqu'un utiliserait-t-il String.Format en C # et VB .NET par opposition aux opérateurs de concaténation (& en VB et + en C #)?

Quelle est la différence principale? Pourquoi tout le monde est-il si intéressé par l'utilisation de String.Format? Je suis très curieux.

166

Je peux voir un certain nombre de raisons:

Lisibilité

string s = string.Format("Hey, {0} it is the {1}st day of {2}.  I feel {3}!", _name, _day, _month, _feeling);

contre:

string s = "Hey," + _name + " it is the " + _day + "st day of " + _month + ".  I feel " + feeling + "!";

Spécificateurs de format (et cela inclut le fait que vous pouvez écrire des formateurs personnalisés)

string s = string.Format("Invoice number: {0:0000}", _invoiceNum);

contre:

string s = "Invoice Number = " + ("0000" + _invoiceNum).Substr(..... /*can't even be bothered to type it*/)

Persistance du modèle de chaîne

Que faire si je veux stocker des modèles de chaîne dans la base de données? Avec le formatage de chaîne:

_id         _translation
  1         Welcome {0} to {1}.  Today is {2}.
  2         You have {0} products in your basket.
  3         Thank-you for your order.  Your {0} will arrive in {1} working days.

contre:

_id         _translation
  1         Welcome
  2         to
  3         .  Today is
  4         . 
  5         You have
  6         products in your basket.
  7         Someone
  8         just shoot
  9         the developer.
394
Moo-Juice

En plus d'être un peu plus facile à lire et d'ajouter quelques opérateurs de plus, il est également avantageux que votre application soit internationalisée. Souvent, les variables sont des nombres ou des mots clés qui seront dans un ordre différent pour différentes langues. En utilisant String.Format, votre code peut rester inchangé tandis que différentes chaînes iront dans les fichiers de ressources. Donc, le code finirait par être

String.Format(resource.GetString("MyResourceString"), str1, str2, str3);

Alors que vos chaînes de ressources finissent par être

Anglais: "blah blah {0} blah blah {1} blah {2}"

Russe: "{0} blet blet blet {2} blet {1}"

Là où le russe peut avoir des règles différentes sur la façon dont les choses sont traitées, l'ordre est différent ou la structure des phrases est différente.

91
doobop

D'abord, je trouve

string s = String.Format(
    "Your order {0} will be delivered on {1:yyyy-MM-dd}. Your total cost is {2:C}.",
    orderNumber,
    orderDeliveryDate,
    orderCost
);

beaucoup plus facile à lire, écrire et maintenir que

string s = "Your order " +
           orderNumber.ToString() +
           " will be delivered on " +
           orderDeliveryDate.ToString("yyyy-MM-dd") +
           "." +
           "Your total cost is " +
           orderCost.ToString("C") + 
           ".";

Regardez combien plus maintenable ce qui suit est

string s = String.Format(
    "Year = {0:yyyy}, Month = {0:MM}, Day = {0:dd}",
    date
);

sur l’alternative où vous devrez répéter date trois fois.

Deuxièmement, les spécificateurs de format fournis par String.Format vous offrent une grande flexibilité quant à la sortie de la chaîne, de manière à ce qu'il soit plus facile à lire, à écrire et à gérer que d'utiliser simplement une ancienne concaténation. En outre, il est plus facile de résoudre les problèmes de culture avec String.Format.

Troisièmement, lorsque les performances importent, String.Format surperformera la concaténation. En coulisse, il utilise un StringBuilder et évite le problème problème de Schlemiel le peintre .

26
jason

Plusieurs raisons:

  1. String.Format() est très puissant. Vous pouvez utiliser des indicateurs de format simples (largeur fixe, devise, longueur des caractères, etc.) directement dans la chaîne de format. Vous pouvez même créer vos propres fournisseurs de format, par exemple pour développer des énumérations, mapper des entrées spécifiques vers des sorties beaucoup plus complexes ou la localisation.
  2. Vous pouvez faire des choses puissantes en plaçant des chaînes de format dans les fichiers de configuration.
  3. String.Format() est souvent plus rapide, car il utilise un StringBuilder et une machine à états efficace en coulisse, alors que la concaténation de chaînes dans .Net est relativement lente. Pour les petites chaînes, la différence est négligeable, mais elle peut être perceptible à mesure que la taille de la chaîne et le nombre de valeurs substituées augmentent.
  4. String.Format() est en réalité plus familier à de nombreux programmeurs, en particulier ceux issus de milieux utilisant des variantes de l’ancienne fonction C printf().

Enfin, n'oubliez pas StringBuilder.AppendFormat(). String.Format() utilise en fait cette méthode en arrière-plan *, et aller directement au StringBuilder peut vous donner une sorte d'approche hybride: utilisez explicitement .Append() (analogue à la concaténation) pour certaines parties d'une chaîne de grande taille, et utilisez .AppendFormat() dans d'autres .


* [modifier] La réponse originale a maintenant 8 ans et j'ai vu depuis une indication indiquant que cela aurait pu changer après l'ajout de l'interpolation de chaînes à .Net. Cependant, je ne suis pas encore retourné à la source de référence pour vérifier le changement.

17
Joel Coehoorn

String.Format ajoute de nombreuses options aux opérateurs de concaténation, notamment la possibilité de spécifier le format spécifique de chaque élément ajouté à la chaîne.

Pour plus de détails sur ce qui est possible, je vous recommande de lire la section relative à MSDN intitulée Composite Formatting . Il explique l'avantage de _String.Format_ (ainsi que de _xxx.WriteLine_ et d'autres méthodes prenant en charge le formatage composite) par rapport aux opérateurs de concaténation normaux.

5
Reed Copsey

Il y a des choses intéressantes sur les aspects de performance dans cette question

Cependant, personnellement, je recommanderais toujours string.Format sauf si les performances sont essentielles pour des raisons de lisibilité.

string.Format("{0}: {1}", key, value);

Est plus lisible que

key + ": " + value

Par exemple. Fournit également une séparation de Nice des préoccupations. Signifie que vous pouvez avoir

string.Format(GetConfigValue("KeyValueFormat"), key, value);

Et changer ensuite le format de votre valeur de clé de "{0}: {1}" à "{0} - {1}" devient un changement de configuration plutôt qu'un changement de code.

string.Format contient également de nombreux formats, nombres entiers, formatage de date, etc.

4
SamStephens

Une des raisons pour lesquelles il n'est pas préférable d'écrire la chaîne telle que 'string +"Value"+ string' est due à la localisation. Dans les cas où la localisation se produit, nous voulons que la chaîne localisée soit correctement formatée, ce qui pourrait être très différent de la langue dans laquelle le code est codé.

Par exemple, nous devons afficher l'erreur suivante dans différentes langues:

MessageBox.Show(String.Format(ErrorManager.GetError("PIDV001").Description, proposalvalue.ProposalSource)

'ErrorCollector.GetError("ERR001").ErrorDescription' renvoie une chaîne telle que "Your ID {0} is not valid". Ce message doit être localisé dans plusieurs langues. Dans ce cas, nous ne pouvons pas utiliser + en C #. Nous devons suivre string.format.

2
user2186941