web-dev-qa-db-fra.com

Dois-je utiliser .ToString () lors de la concaténation de variables chaîne et entier en C #?

int a = 1;
int b = 2;
int sum = a + b;
string expression = "Expression: " + a + " + " + b + " = " + sum;
Console.WriteLine(expression); //displays Expression 1 + 2 = 3

Dois-je utiliser:

string expression = "Expression: " + a + " + " + b + " = " + sum;

ou

string expression = "Expression: " + a.ToString() + " + " + b.ToString() + " = " + result.ToString();

Est-il recommandé d'utiliser ToString() lors de la concaténation de string et int?

19
Akainu

ToString utilisation

Non, vous ne devez pas utiliser ToString ici.

La concaténation de chaînes transforme automatiquement les non-chaînes en chaînes, ce qui signifie que vos deux variantes sont presque¹ identiques:

Lorsqu'un ou les deux opérandes sont de type chaîne, les opérateurs d'addition prédéfinis concaténent la représentation sous forme de chaîne des opérandes.

Source: Spécification du langage C #: opérateur d'addition, MSDN .

Par contre, le premier (sans ToString):

  • Est plus court à écrire,
  • Est plus court à lire,
  • Est plus facile à entretenir et:
  • montre exactement l'intention de l'auteur: concaténer des chaînes.

Alors préférez le premier.

Sous la capuche

Ce qui est aussi intéressant, c'est de voir ce qui se passe sous le capot. Une des façons de le voir est de regarder le code IL dans LINQPad. Ce programme:

void Main()
{
    var a = 3;
    var b = " Hello";
    var c = a + b;
    Console.WriteLine(c);
}

est traduit dans l'IL suivant:

IL_0001:  ldc.i4.3    
IL_0002:  stloc.0     // a
IL_0003:  ldstr       " Hello"
IL_0008:  stloc.1     // b
IL_0009:  ldloc.0     // a
IL_000A:  box         System.Int32
IL_000F:  ldloc.1     // b
IL_0010:  call        System.String.Concat
IL_0015:  stloc.2     // c
IL_0016:  ldloc.2     // c
IL_0017:  call        System.Console.WriteLine

Vous voyez que System.String.Concat? Cela signifie que le code d'origine peut également être écrit comme cela, ce qui se traduit exactement par le même IL:

void Main()
{
    var a = 3;
    var b = " Hello";
    var c = string.Concat(a, b); // This is the line which was changed.
    Console.WriteLine(c);
}

Lorsque vous lisez la documentation de string.Concat(object[]) , vous pouvez apprendre que:

La méthode concatène chaque objet dans args en appelant la méthode ToString sans paramètre de cet objet; il n'ajoute aucun délimiteur.

Cela signifie que ToString est redondant. Aussi:

String.Empty Est utilisé à la place de tout objet nul dans le tableau.

Ce qui gère bien le cas où certains des opérandes sont nuls (voir la note de bas de page 1).

Alors que dans le dernier exemple, la concaténation a été traduite en string.Concat, Il faut également mettre en évidence les optimisations du compilateur:

var a = "Hello " + "World";

se traduit par:

ldstr       "Hello World"
stloc.0

D'autre part:

var a = string.Concat("Hello ", "World");

se traduit par:

ldstr       "Hello "
ldstr       "World"
call        System.String.Concat
stloc.0

Autres alternatives

Il existe bien sûr d'autres façons de concaténer des représentations de chaîne d'objets en C #.

  1. StringBuilder est utilisé lorsque vous devez effectuer de nombreuses opérations de concaténation et aide à réduire le nombre de chaînes intermédiaires créées. Décider si vous devez utiliser un StringBuilder ou une concaténation ordinaire peut ne pas être facile. Utilisez un profileur ou recherchez des réponses pertinentes sur Stack Overflow.

    L'utilisation de StringBuilder a un inconvénient majeur de rendre le code difficile à lire et à maintenir. Pour des cas simples comme celui de votre question, StringBuilder est non seulement nuisible à la lisibilité du code, mais également inutile en termes de performances.

  2. string.Join Doit être utilisé lorsque vous devez ajouter des délimiteurs.

    Évidemment, n'utilisez jamais string.Join Avec un délimiteur vide pour concaténer des chaînes.

  3. string.Format Peut être utilisé lorsque le modèle de chaîne est préféré à la concaténation de chaîne. L'un des cas où vous préférerez peut-être que le message peut être localisé, comme suggéré dans la réponse de kunthet.

    L'utilisation de string.Format Présente plusieurs inconvénients, ce qui la rend inadaptée à des cas simples comme le vôtre:

    • Avec de simples espaces réservés "{0}", il est souvent difficile de savoir quel paramètre va où. Il est fréquent d'inverser par erreur les paramètres ou d'en oublier un. Heureusement, C # 6 introduit enfin interpolation de chaîne qui résout ce problème.

    • Les performances d'exécution peuvent se dégrader. Bien sûr, ne supposez pas que string.Format Est toujours plus lent. Si les performances sont importantes, mesurez deux approches et déterminez laquelle est la plus rapide en fonction de vos résultats réels plutôt que des hypothèses.

    • Le code est légèrement plus long à écrire, plus long à lire et plus difficile à maintenir, bien que cela soit extrêmement mineur et ne devrait pas trop vous déranger.


¹ La différence apparaît lorsque l'un des objets est null. Sans ToString, un null est remplacé par une chaîne vide. Avec ToString, un NullReferenceException est lancé.

33
Arseni Mourzenko

Au lieu de cela, vous devez utiliser le formateur de chaînes. Il est plus facile de formater votre nombre en représentation sous forme de chaîne ou en localisation. par exemple.:

string expression = string.Format("Expression: {0} + {1} = {2}", a, b, sum);

Plus d'informations sur MSDN .

Cependant, le formateur de chaînes est moins lisible (et peut-être aussi les performances) que la concaténation de chaînes.

15
kunthet