Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> C#

String vs StringBuilder ใน C# ใช้ตัวไหนดี

ความแตกต่างหลัก: Mutability

คุณสมบัติString (System.String)StringBuilder (System.Text.StringBuilder)
NatureImmutable (ไม่เปลี่ยนแปลงได้)Mutable (เปลี่ยนแปลงได้)
Concatenationสร้าง Object ใหม่ทุกครั้งแก้ไขใน Buffer เดียว
MemoryAllocate ใหม่ทุกครั้งResizable Buffer (Capacity)
Performanceช้าเมื่อ Concatenate หลายครั้งเร็วสำหรับการต่อ String มาก
Thread SafetyThread-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")
}