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.
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.
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.
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 .
Plusieurs raisons:
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.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.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.
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.
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.
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)
où
'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.