Condividi tramite


Overload e ordine di valutazione di StringBuilder.Append

C# 10 aggiunge il supporto per una migliore interpolazione di stringhe, inclusa la possibilità di impostare come destinazione "gestori" personalizzati oltre alle stringhe. StringBuilder sfrutta questa funzionalità con nuovi overload di Append e AppendLine che accettano un gestore di stringhe interpolate personalizzato. Le chiamate esistenti a questi metodi possono ora avviare l'associazione ai nuovi overload. In generale, il comportamento è identico ma con prestazioni migliorate. Invece di creare prima di tutto una stringa e quindi accodarla, ad esempio, i singoli componenti della stringa interpolata vengono accodati direttamente al generatore. Questo può tuttavia modificare l'ordine di valutazione degli oggetti usati come elementi di formato e ciò può manifestarsi come differenza nel comportamento.

Comportamento precedente

Nelle versioni precedenti una chiamata a:

stringBuilder.Append($"{a} {b}");

Veniva compilata nell'equivalente di:

stringBuilder.Append(string.Format("{0} {1}", a, b));

Ciò significa che viene valutato a, quindi viene valutato b, quindi viene creata una stringa dai risultati di tali valutazioni e quindi tale stringa viene aggiunta al generatore.

Nuovo comportamento

A partire da .NET 6, una chiamata a:

stringBuilder.Append($"{a} {b}");

Viene compilata nell'equivalente di:

var handler = new StringBuilder.AppendInterpolatedStringHandler(1, 2, stringBuilder);
handler.AppendFormatted(a);
handler.AppendLiteral(" ");
handler.AppendFormatted(b);
stringBuilder.Append(ref handler);

Ciò significa che a viene valutato e aggiunto al generatore e quindi b viene valutato e aggiunto al generatore.

Se, ad esempio, a o b costituisce il generatore, come illustrato nel codice seguente, il nuovo ordine di valutazione può provocare un comportamento diverso in fase di esecuzione.

stringBuilder.Append($"{a} {stringBuilder}");

Versione di introduzione

6.0 RC 1

Tipo di modifica che causa un'interruzione

Questa modifica può influire sulla compatibilità dell'origine.

Motivo della modifica

Gli sviluppatori passano spesso stringhe interpolate a StringBuilder, perché risulta più pratico rispetto alla suddivisione manuale della stringa e la chiamata di StringBuilder.Append per ogni parte. Questi nuovi overload consentono la sintassi concisa e offrono la maggior parte delle prestazioni dell'esecuzione delle singole chiamate.

Nella maggior parte dei casi in cui vengono usati StringBuilder.Append e StringBuilder.AppendLine, non si noterà una differenza funzionale. Se si rileva una differenza che risulta problematica, è possibile ripristinare il comportamento precedente aggiungendo un cast a (string) prima della stringa interpolata. Ad esempio:

stringBuilder.Append((string)$"{a} {b}")

Questa opzione non è tuttavia consigliata, a meno che non sia effettivamente necessaria per la compatibilità.

API interessate

Vedi anche