Compartilhar via


Sobrecargas e ordem de avaliação de StringBuilder.Append

O C# 10 adiciona suporte para interpolação aprimorada de cadeia de caracteres, incluindo a capacidade de direcionamento a "identificadores" personalizados além de cadeias de caracteres. StringBuilder aproveita isso com novas sobrecargas de Append e AppendLine que aceitam um identificador de cadeia de caracteres interpolada personalizado. As chamadas existentes a esses métodos agora podem começar a se associar às novas sobrecargas. Em geral, o comportamento é idêntico, mas com desempenho aprimorado. Por exemplo, em vez de uma cadeia de caracteres ser criada primeiro e depois ser acrescentada, os componentes individuais da cadeia de caracteres interpolada são acrescentados diretamente ao construtor. No entanto, isso pode alterar a ordem de avaliação de objetos usados como itens de formato, o que pode se manifestar como uma diferença de comportamento.

Comportamento anterior

Nas versões anteriores, uma chamada a:

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

era compilada com o equivalente a:

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

Isso significa que a é avaliado, depois b é avaliado, uma cadeia de caracteres é criada com os resultados dessas avaliações e depois essa cadeia de caracteres é acrescentada ao construtor.

Novo comportamento

Do .NET 6 em diante, uma chamada a:

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

é compilada para o equivalente a:

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

Isso significa que a é avaliado e acrescentado ao construtor e depois b é avaliado e acrescentado ao construtor.

Se, por exemplo, a ou b for o construtor, conforme mostrado no código a seguir, a nova ordem de avaliação poderá resultar em comportamento diferente em tempo de execução.

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

Versão introduzida

6.0 RC 1

Tipo de alteração interruptiva

Essa alteração pode afetar a compatibilidade da origem.

Motivo da alteração

É comum que os desenvolvedores passem cadeias de caracteres interpoladas para StringBuilder, pois é mais conveniente do que dividir manualmente a cadeia de caracteres e chamar StringBuilder.Append para cada parte. Essas novas sobrecargas permitem uma sintaxe concisa e a maior parte do desempenho de fazer as chamadas individuais.

Na maioria dos casos em que StringBuilder.Append e StringBuilder.AppendLine são usados, você não observará uma diferença funcional. Se você encontrar uma diferença que se mostre problemática, restaure o comportamento anterior adicionando uma conversão a (string) antes da cadeia de caracteres interpolada. Por exemplo:

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

No entanto, isso não é recomendado, a menos que seja realmente necessário por motivo de compatibilidade.

APIs afetadas

Confira também