StringBuilder.Append 오버로드 및 평가 순서

C# 10에서는 문자열 외에 사용자 지정 “처리기”를 대상으로 지정하는 기능을 포함하여 향상된 문자열 보간을 지원합니다. StringBuilder는 사용자 지정 보간된 문자열 처리기를 허용하는 AppendAppendLine의 새 오버로드를 통해 이를 활용합니다. 이제 이러한 메서드에 대한 기존 호출이 새 오버로드에 대한 바인딩을 시작할 수 있습니다. 일반적으로 동작은 동일하지만 성능이 향상됩니다. 예를 들어, 문자열이 먼저 생성된 후 문자열이 추가되는 것과는 달리 보간된 문자열의 개별 구성 요소는 작성기에 직접 추가됩니다. 그러나 이로 인해 서식 항목으로 사용되는 개체의 평가 순서가 변경될 수 있으므로 동작의 차이로 매니페스트될 수 있습니다.

이전 동작

이전 버전에서는 다음에 대한 호출이

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

다음에 해당하는 항목으로 컴파일됩니다.

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

즉, a가 평가되고, b가 평가되고, 해당 평가의 결과에서 문자열이 생성된 다음, 해당 문자열이 작성기에 추가됩니다.

새 동작

.NET 6부터 다음에 대한 호출이

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

다음에 해당하는 항목으로 컴파일됩니다.

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

즉, a가 평가되고 작성기에 추가된 다음, b가 평가되고 작성기에 추가됩니다.

예를 들어, 다음 코드와 같이 a 또는 b 자체가 작성기인 경우 새 평가 순서로 인해 런타임에 다른 동작이 발생할 수 있습니다.

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

도입된 버전

6.0 RC 1

호환성이 손상되는 변경의 형식

이 변경은 소스 호환성에 영향을 줄 수 있습니다.

변경 이유

문자열을 수동으로 분할하고 각 부분에 대해 StringBuilder.Append를 호출하는 것보다 더 편리하기 때문에 개발자가 보간된 문자열을 StringBuilder에 전달하는 것이 일반적입니다. 이러한 새 오버로드를 사용하면 구문이 간결해지고 개별 호출을 수행하는 데 최대 성능을 사용할 수 있습니다.

StringBuilder.AppendStringBuilder.AppendLine이 사용되는 대부분의 경우에는 기능적 차이를 알 수 없습니다. 문제가 있음을 알 수 있는 차이를 찾은 경우 보간된 문자열 앞의 (string)에 캐스트를 추가하여 이전 동작을 복원할 수 있습니다. 예시:

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

그러나 실제로 호환성을 위해 필요한 경우가 아니면 이 방법은 권장되지 않습니다.

영향을 받는 API

참고 항목