Dal momento che non credo che le risposte qui riguardino tutto, vorrei fare una piccola aggiunta qui.
Console.WriteLine(string format, params object[] pars) chiamate string.Format . Il '+' implica la concatenazione di stringhe. Non penso che questo abbia sempre a che fare con lo stile; Tendo a mescolare i due stili a seconda del contesto in cui mi trovo.
Risposta breve
La decisione che stai affrontando ha a che fare con l'allocazione delle stringhe. Proverò a renderlo semplice.
Di 'che hai
string s = a + "foo" + b;
Se lo esegui, valuterà come segue:
string tmp1 = a;
string tmp2 = "foo"
string tmp3 = concat(tmp1, tmp2);
string tmp4 = b;
string s = concat(tmp3, tmp4);
tmpqui non è in realtà una variabile locale, ma è temporanea per JIT (è inserita nello stack IL). Se si ldstrinserisce una stringa nello stack (come in IL per i letterali), si inserisce un riferimento a un puntatore di stringa nello stack.
Nel momento in cui chiami concat questo riferimento diventa un problema, perché non è disponibile alcun riferimento di stringa che contenga entrambe le stringhe. Ciò significa che .NET deve allocare un nuovo blocco di memoria e quindi riempirlo con le due stringhe. Il motivo per cui questo è un problema è perché l'allocazione è relativamente costosa.
Il che cambia la domanda in: Come è possibile ridurre il numero di concatoperazioni?
Quindi, la risposta approssimativa è: string.Formatper> 1 concat, '+' funzionerà bene per 1 concat. E se non ti interessa fare ottimizzazioni di micro-prestazioni, string.Formatfunzionerà bene nel caso generale.
Una nota sulla cultura
E poi c'è qualcosa chiamato cultura ...
string.Formatti consente di utilizzare CultureInfonella formattazione. Un semplice operatore '+' utilizza la cultura corrente.
Questa è un'osservazione particolarmente importante se stai scrivendo formati di file e f.ex. doublevalori che 'aggiungi' a una stringa. Su macchine diverse, potresti finire con stringhe diverse se non le usi string.Formatcon un esplicito CultureInfo.
F.ex. considera cosa succede se cambi un '.' per un "," durante la scrittura del file con valori separati da virgola ... in olandese il separatore decimale è una virgola, quindi l'utente potrebbe semplicemente ricevere una sorpresa "divertente".
Risposta più dettagliata
Se non si conosce in anticipo la dimensione esatta della stringa, è consigliabile utilizzare una politica come questa per sovrallocare i buffer utilizzati. Lo spazio lento viene prima riempito, dopo di che i dati vengono copiati.
Crescere significa allocare un nuovo blocco di memoria e copiare i vecchi dati nel nuovo buffer. Il vecchio blocco di memoria può quindi essere rilasciato. A questo punto ottieni la linea di fondo: crescere è un'operazione costosa.
Il modo più pratico per farlo è utilizzare una politica di sovrallocazione. La politica più comune è quella di sovrallocare i buffer con potenze di 2. Naturalmente, devi farlo un po 'più intelligente di quello (poiché non ha senso crescere da 1,2,4,8 se sai già che hai bisogno di 128 caratteri ) ma ottieni l'immagine. La politica garantisce che non siano necessarie troppe operazioni costose che ho descritto sopra.
StringBuilderè una classe che fondamentalmente sovralloca il buffer sottostante in potenze di due. string.Formatutilizza StringBuildersotto il cofano.
Questo rende la tua decisione un compromesso di base tra overallocate-and-append (-multiple) (w / wo culture) o semplicemente allocate-and-append.
string.Formatche non utilizza alcuna funzionalità di formattazione composita (cioè semplicemente semplice{0}) e sostituirli con la concatenazione di stringhe notevolmente più veloce. Mi chiedo che una simile impresa sia realizzabile con un riscrittore di IL esistente come PostSharp.