StringBuilder.Append aşırı yüklemeleri ve değerlendirme sırası
C# 10, dizelere ek olarak özel "işleyicileri" hedefleme özelliği de dahil olmak üzere daha iyi dize ilişkilendirme desteği ekler. StringBuilder, özel bir ilişkilendirilmiş dize işleyicisini kabul eden yeni AppendLine ve aşırı yüklemeleriyle Append bundan yararlanır. Bu yöntemlere yapılan mevcut çağrılar artık yeni aşırı yüklemelere bağlamaya başlayabilir. Genel olarak davranış aynıdır ancak performansı iyileştirilir. Örneğin, önce bir dize oluşturulup sonra bu dize eklenmek yerine, ilişkilendirilmiş dizenin tek tek bileşenleri doğrudan oluşturucuya eklenir. Ancak bu, biçim öğeleri olarak kullanılan nesnelerin değerlendirme sırasını değiştirebilir ve bu durum davranışta bir fark olarak ortaya çıkar.
Önceki davranış
Önceki sürümlerde şu çağrı:
stringBuilder.Append($"{a} {b}");
eşdeğerine derlenmiş:
stringBuilder.Append(string.Format("{0} {1}", a, b));
Bu, a
değerlendirilir, sonra b
değerlendirilir, sonra bu değerlendirmelerin sonuçlarından bir dize oluşturulur ve sonra bu dize oluşturucuya eklenir.
Yeni davranış
.NET 6'dan başlayarak şunların çağrısı yapılır:
stringBuilder.Append($"{a} {b}");
şu eşdeğerine derler:
var handler = new StringBuilder.AppendInterpolatedStringHandler(1, 2, stringBuilder);
handler.AppendFormatted(a);
handler.AppendLiteral(" ");
handler.AppendFormatted(b);
stringBuilder.Append(ref handler);
Bu, değerlendirilip oluşturucuya eklendiği ve ardından b
değerlendirilip oluşturucuya eklendiği anlamına gelira
.
Örneğin, aşağıdaki kodda gösterildiği gibi oluşturucunun kendisi a
veya b
oluşturucusuysa, yeni değerlendirme sırası çalışma zamanında farklı davranışlara neden olabilir.
stringBuilder.Append($"{a} {stringBuilder}");
Sürüm kullanıma sunulmuştur
6.0 RC 1
Hataya neden olan değişikliğin türü
Bu değişiklik kaynak uyumluluğunu etkileyebilir.
Değişiklik nedeni
Her bölüm için dizeyi el ile bölmekten ve çağırmaktan StringBuilder.Append daha kullanışlı olduğundan, geliştiricilerin ilişkilendirilmiş dizeleri 'ye StringBuildergeçirmesi yaygın bir durumdır. Bu yeni aşırı yüklemeler, kısa söz dizimini ve tek tek çağrıları gerçekleştirme performansının çoğunu etkinleştirir.
Önerilen eylem
ve StringBuilder.AppendLine kullanılan çoğu durumda StringBuilder.Append işlevsel bir fark fark etmezsiniz. Sorunlu olduğunu kanıtlayan bir fark bulursanız, ilişkilendirme dizesinden önce bir (string)
atama ekleyerek önceki davranışı geri yükleyebilirsiniz. Örneğin:
stringBuilder.Append((string)$"{a} {b}")
Ancak, uyumluluk için gerçekten gerekli olmadığı sürece bu önerilmez.