Dovrei usare .ToString () durante la concatenazione di variabili stringa e numero intero in C #?


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

Dovrei usare:

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

o

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

Si consiglia di utilizzare ToString()durante la concatenazione stringe int?


6
In a + "" + b + ""o "" + a + b + "", non importa: è tutta concatenazione di stringhe. In a + b + ""esso importa: ae bvengono aggiunti per primi.
Tim S.

4
Nota a margine: in VB.NET, questa ambiguità viene evitata avendo un operatore di concatenazione di stringhe esplicito : "Expression: " + agenererà un errore di tempo di compilazione (con Option Strict On), "Expression: " & aeseguirà la concatenazione di stringhe.
Heinzi,

Il primo codice comporterà la boxe (da int a Int32), il secondo no. Il secondo è ovviamente più veloce.
Alfabeti casuali

Risposte:


33

ToString uso

No, non dovresti usare ToStringqui.

La concatenazione di stringhe trasforma automaticamente le non stringhe in stringhe, il che significa che le tue due varianti sono quasi¹ identiche:

Quando uno o entrambi gli operandi sono di tipo stringa, gli operatori addizione predefiniti concatenano la rappresentazione di stringa degli operandi.

Fonte: Specifica del linguaggio C #: operatore addizione, MSDN .

D'altra parte, il primo (senza ToString):

  • È più breve da scrivere,
  • È più breve da leggere,
  • È più facile da mantenere e:
  • mostra esattamente l'intenzione dell'autore: concatenare le stringhe.

Quindi preferisci il primo.

Sotto il cappuccio

Ciò che è anche interessante è vedere cosa succede sotto il cofano. Uno dei modi per vederlo è guardare il codice IL all'interno di LINQPad. Questo programma:

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

è tradotto nel seguente IL:

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

Vedi quello System.String.Concat? Ciò significa che il codice originale può essere scritto anche in questo modo, che si traduce esattamente nello stesso 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);
}

Quando leggi la documentazione distring.Concat(object[]) , puoi imparare che:

Il metodo concatena ogni oggetto in arg chiamando il ToStringmetodo senza parametri di quell'oggetto; non aggiunge alcun delimitatore.

Ciò significa che ToStringè ridondante. Anche:

String.Empty viene utilizzato al posto di qualsiasi oggetto null nell'array.

Che gestisce bene il caso in cui alcuni degli operandi sono nulli (vedere la nota 1).

Mentre nell'ultimo esempio, la concatenazione è stata tradotta in string.Concat, si dovrebbero anche evidenziare le ottimizzazioni del compilatore:

var a = "Hello " + "World";

è tradotto in:

ldstr       "Hello World"
stloc.0

D'altro canto:

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

è tradotto in:

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

Altre alternative

Esistono ovviamente altri modi per concatenare rappresentazioni di stringhe di oggetti in C #.

  1. StringBuilderviene utilizzato quando è necessario eseguire molte operazioni di concatenazione e consente di ridurre il numero di stringhe intermedie create. Decidere se utilizzare una StringBuilderconcatenazione normale o ordinaria potrebbe non essere facile. Utilizzare un profiler o cercare risposte pertinenti su StackTranslate.it.

    L'utilizzo StringBuilderha un grosso svantaggio nel rendere il codice difficile da leggere e mantenere. Per casi semplici come quello in questione, StringBuildernon è solo dannoso per la leggibilità del codice, ma è anche inutile in termini di prestazioni.

  2. string.Join dovrebbe essere usato quando è necessario aggiungere delimitatori.

    Ovviamente, non utilizzare mai string.Joincon un delimitatore vuoto per concatenare le stringhe.

  3. string.Formatpuò essere utilizzato quando si preferisce il modello di stringa alla concatenazione di stringhe. Uno dei casi in cui potresti preferire questo è quando il messaggio può essere localizzato, come suggerito nella risposta di kunthet.

    L'utilizzo string.Formatpresenta diversi inconvenienti che lo rendono inadatto per casi semplici come il tuo:

    • Con semplici segnaposto "{0}", spesso non è chiaro quale parametro vada dove. È frequente invertire erroneamente i parametri o dimenticarsene uno. Fortunatamente, C # 6 introduce finalmente l' interpolazione di stringhe che risolve questo problema.

    • Le prestazioni di runtime potrebbero peggiorare. Certo, non dare per scontato che string.Formatsia sempre più lento. Se le prestazioni sono importanti, misurare due approcci e determinare quale è più veloce in base ai risultati effettivi anziché alle ipotesi.

    • Il codice è leggermente più lungo da scrivere, più lungo da leggere e più difficile da mantenere, anche se questo è estremamente minore e non dovrebbe disturbarti troppo.


¹ La differenza appare quando uno degli oggetti è null. Senza ToString, a nullviene sostituito da una stringa vuota. Con ToStringuna NullReferenceExceptionviene generata.


1
Proprio per questo motivo (comportamento imprevedibile), concatenare stringhe con la +è considerata una cattiva pratica nella maggior parte delle lingue. In questo caso lo userei string.Concat, in molti casi string.Formatè meglio. Non è certamente Pythonic da usare +, e poiché PEP 3101 %è scoraggiato anche a favore str.format.
Arda Xi,

2
Sostituire una stringa vuota per null"gestirla bene"? Bene, non è così male come "in errore riprendi successivo" ...
Deduplicatore

Sotto il cofano, se concatenate senza chiamare .ToString (), la boxe accadrà ... e Concat(object[])verrà utilizzata al posto di Concat(string[]). Quindi in "string " + irealtà non è identico a"string " + i.ToString()
Alfabeti casuali

@RandomAlphabets: punto valido. Tuttavia, la differenza è semplicemente la posizione di ToString(): codice OP in un caso, System.String.Concatimplementazione nell'altro caso. Quindi, la risposta rimane valida: non scrivere il codice che non ha alcun vantaggio.
Arseni Mourzenko,

15

Invece, dovresti usare il formattatore di stringhe. È più semplice formattare il numero in rappresentazione di stringa o localizzazione. per esempio:

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

Maggiori informazioni su MSDN .

Tuttavia, il formattatore di stringhe è meno leggibile (e forse anche delle prestazioni) della concatenazione di stringhe.


6
Vuoi spiegare perché questa opzione è migliore?
Ingegnere mondiale,

@WorldEngineer: ho aggiornato la spiegazione.
Kunthet,

12
Non conosco tutti gli altri, ma in realtà lo trovo più leggibile. Forse perché sono cresciuto con C dove s [n] printf è l'unica opzione realistica per questo tipo di codice.
Jules,

2
Ma in questo modo dà tre fonti di errori anziché uno. Quando aggiungi qualcosa nella stringa, devi 1) cambiare la stringa di formato, 2) non dimenticare di aggiungere un nuovo parametro nell'elenco, 3) provare a scegliere il punto corretto nell'elenco in cui posizionare il nuovo parametro.
Ruslan,

2
Voglio solo entrare e farti conoscere l'imminente funzione di interpolazione delle stringhe in C # 6 .. Scriverai "Espressione: \ {a} + \ {b} = \ {sum}" per ottenere lo stesso risultato. codeproject.com/Articles/846566/…
cwap

-2

Se si utilizza la +concatenazione, essa stessa utilizza il String.Concatmetodo. La stringa stessa non espone un operatore +.

per esempio:

int i = 10;
string str = "hello" + i;

è compilato in:

int i = 10;
object o1 = "hello";
object o2 = i; // Note boxing
string str = string.Concat(o1, o2);

Se chiami direttamente ToString, eviterai il pugilato e chiamerai il Concat(string, string)sovraccarico. Quindi la ToStringchiamata sarà leggermente più efficiente sebbene non abbastanza significativa. È meglio andare con l'esempio che ritieni più leggibile.


2
questo sembra semplicemente ripetere i punti fatti e spiegati nella risposta precedente : "La concatenazione di stringhe trasforma automaticamente le non stringhe in stringhe ..."
moscerino
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.