ความแตกต่างหลัก: Mutability
| คุณสมบัติ | String (System.String) | StringBuilder (System.Text.StringBuilder) |
| Nature | Immutable (ไม่เปลี่ยนแปลงได้) | Mutable (เปลี่ยนแปลงได้) |
| Concatenation | สร้าง Object ใหม่ทุกครั้ง | แก้ไขใน Buffer เดียว |
| Memory | Allocate ใหม่ทุกครั้ง | Resizable Buffer (Capacity) |
| Performance | ช้าเมื่อ Concatenate หลายครั้ง | เร็วสำหรับการต่อ String มาก |
| Thread Safety | Thread-Safe (Immutable) | Not Thread-Safe |
ตัวอย่างเปรียบเทียบ
using System;
using System.Text;
class DemoApplication
{
public static void Main()
{
// String - Immutable
string systemString = "Hello";
StringConcat(systemString);
Console.WriteLine("String Result: " + systemString); // ยังคง "Hello"
// StringBuilder - Mutable
StringBuilder sb = new StringBuilder("Hello");
StringBuilderConcat(sb);
Console.WriteLine("StringBuilder Result: " + sb); // กลายเป็น "Hello World"
}
static void StringConcat(string s)
{
string append = " World";
s = String.Concat(s, append); // สร้าง String ใหม่ Local Variable
// s ใน Main() ไม่เปลี่ยน เพราะ String Immutable
}
static void StringBuilderConcat(StringBuilder sb)
{
sb.Append(" World"); // แก้ไข Buffer เดียวกัน
// sb ใน Main() เปลี่ยน เพราะ Reference Type + Mutable
}
}
Output
String Result: Hello
StringBuilder Result: Hello World
เมื่อไหร่ควรใช้ String
- ✅ String คงที่ (Constants, Literals)
- ✅ Concatenation น้อย (< 5-10 ครั้ง)
- ✅ Dictionary Key, Switch Expression, Pattern Matching
- ✅ Interpolation:
$"Hello {name}" (Compiler Optimize ให้)
- ✅ Thread-Safe Context
เมื่อไหร่ควรใช้ StringBuilder
- ✅ Loop ที่ต่อ String หลายรอบ (
for, foreach)
- ✅ String ใหญ่ / Complex Building (HTML, JSON, SQL)
- ✅ Performance Critical Path
- ✅ ต้องการ
AppendLine, AppendFormat, Clear
Performance Benchmark
// ❌ Bad: String ใน Loop
string s = "";
for (int i = 0; i < 10000; i++) s += i; // 10000 Allocations!
// ✅ Good: StringBuilder
var sb = new StringBuilder();
for (int i = 0; i < 10000; i++) sb.Append(i);
string result = sb.ToString(); // 1 Allocation
// ✅ Good: String.Join (Optimized)
string result = string.Join("", Enumerable.Range(0, 10000).Select(i => i.ToString()));
// ✅ Good: String.Create (Span-based, .NET Core 2.1+)
string result = String.Create(10000 * 5, 10000, (span, count) =>
{
for (int i = 0; i < count; i++)
i.TryFormat(span.Slice(i * 5), out _);
});
StringBuilder Tips
// Pre-allocate Capacity (หลีกเลี่ยง Resize)
var sb = new StringBuilder(1000); // Initial Capacity
// Method Chaining
sb.Append("Hello").Append(" ").Append("World");
// Clear และ Reuse
sb.Clear();
sb.Append("New Content");
// Insert/Replace/Remove
sb.Insert(5, "Beautiful ");
sb.Replace("World", "Universe");
sb.Remove(0, 5);
String Interpolation vs Concatenation
// Compiler แปลง Interpolation เป็น String.Concat หรือ StringBuilder อัตโนมัติ
string s1 = $"{a} {b} {c}"; // → String.Concat(a, " ", b, " ", c)
// ใน Loop ให้ใช้ StringBuilder
var sb = new StringBuilder();
foreach (var item in items)
{
sb.AppendLine($"{item.Id}: {item.Name}"); // ดีกว่า sb.Append($"{item.Id}: {item.Name}\n")
}