Udostępnij za pośrednictwem


Przeciążenia StringBuilder.Append i kolejność oceny

Język C# 10 dodaje obsługę lepszej interpolacji ciągów, w tym możliwość kierowania niestandardowych "procedur obsługi" oprócz ciągów. StringBuilderKorzysta z tego z nowych przeciążeń i AppendLine akceptuje niestandardową procedurę obsługi ciągów Append interpolowanych. Istniejące wywołania tych metod mogą teraz zacząć wiązać się z nowymi przeciążeniami. Ogólnie rzecz biorąc, zachowanie jest identyczne, ale z lepszą wydajnością. Na przykład zamiast najpierw tworzonego ciągu, a następnie dołączania tego ciągu poszczególne składniki ciągu interpolowanego są dołączane bezpośrednio do konstruktora. Może to jednak zmienić kolejność oceny obiektów używanych jako elementy formatu, co może przejawiać się różnicą w zachowaniu.

Poprzednie zachowanie

W poprzednich wersjach wywołanie metody :

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

skompilowany na odpowiednik:

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

Oznacza a to, że jest obliczany, a następnie b jest obliczany, a następnie ciąg jest tworzony na podstawie wyników tych ocen, a następnie ten ciąg jest dołączany do konstruktora.

Nowe zachowanie

Począwszy od platformy .NET 6, wywołanie metody :

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

kompiluje do odpowiednika:

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

Oznacza to, że a narzędzie jest oceniane i dołączane do konstruktora, a następnie b jest oceniane i dołączane do konstruktora.

Jeśli na przykład konstruktor a lub b sam jest konstruktorem, jak pokazano w poniższym kodzie, nowa kolejność oceny może spowodować różne zachowanie w czasie wykonywania.

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

Wprowadzona wersja

6.0 RC 1

Typ zmiany powodującej niezgodność

Ta zmiana może mieć wpływ na zgodność źródła.

Przyczyna wprowadzenia zmiany

Deweloperzy często przekazują ciągi interpolowane do StringBuilderelementu , ponieważ jest to wygodniejsze niż ręczne dzielenie ciągu w górę i wywoływanie StringBuilder.Append dla każdej części. Te nowe przeciążenia umożliwiają zwięzłą składnię i większość wydajności wykonywania poszczególnych wywołań.

W większości przypadków, w których StringBuilder.Append i StringBuilder.AppendLine są używane, nie zauważysz różnicy funkcjonalnej. Jeśli znajdziesz różnicę, która okaże się problematyczna, możesz przywrócić poprzednie zachowanie, dodając rzutowanie do (string) wcześniejszego ciągu interpolowanego. Na przykład:

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

Nie jest to jednak zalecane, chyba że jest to rzeczywiście wymagane do zapewnienia zgodności.

Dotyczy interfejsów API

Zobacz też