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ń.
Zalecana akcja
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.