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.
Azione consigliata
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à.