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í.
Doporučená akce
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ě.