StringBuilder.Append-Überladungen und Auswertungsreihenfolge

C# 10 bietet Unterstützung für eine bessere Zeichenfolgeninterpolation, einschließlich der Möglichkeit, neben Zeichenfolgen auch benutzerdefinierte „Handler“ als Ziel zu verwenden. StringBuilder nutzt dies mit neuen Überladungen von Append und AppendLine, die einen benutzerdefiniert interpolierten Zeichenfolgenhandler akzeptieren. Vorhandene Aufrufe dieser Methoden können jetzt mit der Bindung an die neuen Überladungen beginnen. Im Allgemeinen ist das Verhalten identisch, die Leistung jedoch verbessert. Anstatt beispielsweise zuerst eine Zeichenfolge zu erstellen und diese Zeichenfolge dann anzufügen, werden die einzelnen Komponenten der interpolierten Zeichenfolge direkt an den Generator angefügt. Dies kann jedoch die Auswertungsreihenfolge von Objekten ändern, die als Formatelemente verwendet werden, was zu einem veränderten Verhalten führen kann.

Vorheriges Verhalten

In früheren Versionen ein Aufruf von:

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

kompiliert in die Entsprechung von:

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

Dies bedeutet, dass a ausgewertet, dann b ausgewertet, dann eine Zeichenfolge aus den Ergebnissen dieser Auswertungen erstellt und diese Zeichenfolge dann an den Generator angefügt wird.

Neues Verhalten

Ab .NET 6 ein Aufruf von:

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

kompiliert in die Entsprechung von:

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

Dies bedeutet, dass a ausgewertet und an den Generator angefügt wird, und dann b ausgewertet und an den Generator angefügt wird.

Wenn beispielsweise a oder b selbst der Generator ist, wie im folgenden Code gezeigt, kann die neue Auswertungsreihenfolge während der Laufzeit zu einem anderen Verhalten führen.

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

Eingeführt in Version

6.0 RC 1

Typ des Breaking Changes

Diese Änderung kann sich auf die Quellkompatibilität auswirken.

Grund für die Änderung

Es ist üblich, dass Entwickler*innen interpolierte Zeichenfolgen an StringBuilder übergeben, da das praktischer ist, als die Zeichenfolge manuell zu teilen und für jeden Teil StringBuilder.Append aufzurufen. Diese neuen Überladungen ermöglichen die präzise Syntax und den größten Teil der Leistung der einzelnen Aufrufe.

In den meisten Fällen, in denen StringBuilder.Append und StringBuilder.AppendLine verwendet werden, bemerken Sie keinen funktionalen Unterschied. Wenn Ihnen ein problematischer Unterschied auffällt, können Sie das frühere Verhalten wiederherstellen, indem Sie eine Umwandlung in (string) vor die interpolierte Zeichenfolge einfügen. Beispiel:

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

Dies wird jedoch nicht empfohlen, wenn es nicht aus Kompatibilitätsgründen erforderlich ist.

Betroffene APIs

Siehe auch