C#에서 문자열을 다루다 보면 string과 StringBuilder, 두 가지 타입을 자주 접하게 됩니다. 겉보기에는 비슷해 보이지만, 내부적으로 문자열 값을 저장하고 변경하는 방식이 완전히 다르며, 이는 프로그램의 성능과 메모리 사용량에 큰 영향을 미칩니다. 이번 글에서는 가변 문자열과 불변 문자열의 차이를 예제 코드와 함께 살펴보겠습니다.
가변 문자열(Mutable String): StringBuilder
C#에서 StringBuilder는 대표적인 가변(mutable) 문자열입니다. StringBuilder를 사용하면 이미 생성된 문자열에 문자를 추가하거나 삭제하여 길이를 자유롭게 확장할 수 있습니다. 일반 string은 한 번 생성되면 내용을 바꿀 수 없지만, StringBuilder는 기존 객체 그대로 수정·확장이 가능하기 때문에 새로운 객체를 반복적으로 메모리에 생성하지 않습니다.
StringBuilder는 다음과 같이 선언합니다.
StringBuilder str = new StringBuilder();
아래 예제를 통해 C#에서 StringBuilder를 사용하는 방법을 알아보겠습니다.
예제
using System;
using System.Text;
public class Program {
public static void Main() {
StringBuilder str = new StringBuilder("Web World!!", 30);
str.Replace("World", "Arena");
Console.WriteLine(str);
}
}
실행 결과
Web Arena!!
위 예제에서는 초기 용량(capacity) 30으로 StringBuilder 객체를 생성한 뒤, Replace() 메서드를 사용해 "World"라는 단어를 "Arena"로 교체했습니다. 이 과정에서 기존 객체의 내용만 변경되므로, 문자열 조작이 많은 코드에서도 성능 저하 없이 효율적으로 동작합니다.
불변 문자열(Immutable String): string
C#의 string은 불변(immutable) 문자열입니다. 문자열이 한 번 생성되면 그 내용을 직접 변경할 수 없으며, 문자열을 수정하는 것처럼 보이는 모든 연산에서는 실제로 매번 새로운 메모리 공간에 새로운 객체가 생성됩니다.
즉, 문자열을 연결하거나 일부를 교체하면 기존 문자열이 바뀌는 것이 아니라, 수정된 내용을 담은 완전히 새로운 문자열 객체가 만들어집니다. 따라서 반복적인 문자열 조작이 필요한 경우에는 StringBuilder를 사용하는 것이 권장됩니다.
string은 다음과 같이 선언합니다.
string str = "tim";
다음은 두 개의 문자열을 비교하는 예제입니다.
예제
using System;
namespace StringApplication {
class StringProg {
static void Main(string[] args) {
string str1 = "Steve";
string str2 = "Ben";
if (String.Compare(str1, str2) == 0) {
Console.WriteLine(str1 + " and " + str2 + " are equal strings.");
} else {
Console.WriteLine(str1 + " and " + str2 + " are not equal strings.");
}
Console.ReadKey();
}
}
}
실행 결과
Steve and Ben are not equal strings.
String.Compare() 메서드는 두 문자열이 동일하면 0을 반환합니다. 위 예제에서는 "Steve"와 "Ben"이 서로 다른 문자열이므로, 두 문자열이 같지 않다는 결과가 출력됩니다.
핵심 차이점 요약
| 구분 | string (불변) | StringBuilder (가변) |
|---|---|---|
| 값 변경 | 생성 후 변경 불가 | 생성 후 수정·확장 가능 |
| 메모리 처리 | 수정 시마다 새 객체 생성 | 기존 객체 내에서 수정 |
| 성능 | 문자열 조작이 잦으면 비효율적 | 반복적인 문자열 조작에 유리 |
| 네임스페이스 | System | System.Text |
정리하자면, 값이 거의 변하지 않는 문자열이라면 일반 string을 사용하고, 루프 안에서 문자열을 계속 붙이거나 수정하는 작업이라면 StringBuilder를 사용하는 것이 올바른 선택입니다.