Sdílet prostřednictvím


StringBuilder.Append přetížení a pořadí vyhodnocení

C# 10 přidává podporu pro lepší interpolaci řetězců, včetně možnosti cílit na vlastní "obslužné rutiny" kromě řetězců. StringBuilder využívá to s novými přetíženími Append a AppendLine které přijímají vlastní interpolovanou obslužnou rutinu řetězců. Existující volání těchto metod teď mohou začít vazby na nové přetížení. Obecně platí, že chování je stejné, ale s vylepšeným výkonem. Například místo prvního vytvoření řetězce a následného připojení tohoto řetězce se jednotlivé komponenty interpolovaného řetězce připojují přímo k tvůrci. To však může změnit pořadí vyhodnocení objektů použitých jako formát položek, které se mohou projevit jako rozdíl v chování.

Předchozí chování

V předchozích verzích volání:

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

zkompilováno na ekvivalent:

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

To znamená a , že se vyhodnocuje, pak b se vyhodnotí řetězec, vytvoří se z výsledků těchto vyhodnocení a pak se tento řetězec připojí k tvůrci.

Nové chování

Od verze .NET 6 volání:

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

kompiluje se na ekvivalent:

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

To znamená, že a se vyhodnotí a připojí k tvůrci a pak b se vyhodnotí a připojí k tvůrci.

Pokud je například tvůrce a nebo b sám tvůrce, jak je znázorněno v následujícím kódu, může nové pořadí vyhodnocení vést k jinému chování za běhu.

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

Zavedená verze

6.0 RC 1

Typ zásadní změny

Tato změna může mít vliv na kompatibilitu zdroje.

Důvod změny

Vývojáři obvykle předávají interpolované řetězce StringBuilder, protože je pohodlnější než ruční rozdělení řetězce nahoru a volání StringBuilder.Append pro každou část. Tato nová přetížení umožňují stručnou syntaxi a většinu výkonu jednotlivých volání.

Ve většině případů, kdy StringBuilder.Append a StringBuilder.AppendLine které se používají, si nevšimnete funkčního rozdílu. Pokud zjistíte rozdíl, který je problematický, můžete předchozí chování obnovit přidáním přetypování (string) před interpolovaný řetězec. Příklad:

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

To se ale nedoporučuje, pokud to není skutečně nutné kvůli kompatibilitě.

Ovlivněná rozhraní API

Viz také