เมธอด Equals(object) ของ StringBuilder เปรียบเทียบ Reference Equality (อ้างอิงออบเจ็กต์เดียวกัน) ไม่ใช่เปรียบเทียบเนื้อหาสตริง ต้องใช้ ToString() หรือ StringBuilder.Equals(StringBuilder) (Extension) สำหรับเปรียบเทียบค่า
ตัวอย่างที่ 1: Reference Equality (พฤติกรรมเริ่มต้น)
using System;
using System.Text;
public class Demo
{
public static void Main(string[] args)
{
StringBuilder strBuilder1 = new StringBuilder("Tim");
StringBuilder strBuilder2 = new StringBuilder("Tom");
StringBuilder strBuilder3 = new StringBuilder();
// strBuilder2 อ้างอิงไปที่ strBuilder3 เดียวกัน
strBuilder2 = strBuilder3;
// เปรียบเทียบ Reference (strBuilder3 กับ strBuilder2 คือออบเจ็กต์เดียวกัน)
Console.WriteLine("StringBuilder3 เท่ากับ StringBuilder2? = " + strBuilder3.Equals(strBuilder2));
}
}
ผลลัพธ์
StringBuilder3 เท่ากับ StringBuilder2? = True
ตัวอย่างที่ 2: StringBuilder สองออบเจ็กต์ที่มีค่าเหมือนกัน
using System;
using System.Text;
public class Demo
{
public static void Main(string[] args)
{
StringBuilder strBuilder1 = new StringBuilder("Jacob");
StringBuilder strBuilder2 = new StringBuilder("Jacob");
// Equals เริ่มต้นเปรียบเทียบ Reference -> False (คนละออบเจ็กต์)
Console.WriteLine("StringBuilder1 เท่ากับ StringBuilder2? (Reference) = " + strBuilder2.Equals(strBuilder1));
// วิธีที่ถูกต้อง: เปรียบเทียบค่าเนื้อหา
Console.WriteLine("StringBuilder1 เท่ากับ StringBuilder2? (Value) = " + strBuilder1.ToString().Equals(strBuilder2.ToString()));
// หรือใช้ SequenceEqual (LINQ) - เปรียบเทียบ Char ทีละตัว
Console.WriteLine("SequenceEqual = " + strBuilder1.ToString().SequenceEqual(strBuilder2.ToString()));
}
}
ผลลัพธ์
StringBuilder1 เท่ากับ StringBuilder2? (Reference) = False StringBuilder1 เท่ากับ StringBuilder2? (Value) = True SequenceEqual = True
วิธีเปรียบเทียบ StringBuilder ที่ถูกต้อง
| วิธี | โค้ด | หมายเหตุ |
|---|---|---|
| ToString().Equals() | sb1.ToString().Equals(sb2.ToString()) | ง่ายที่สุด สร้างสตริงใหม่ 2 ตัว |
| String.Equals (Static) | String.Equals(sb1.ToString(), sb2.ToString()) | จัดการ null ได้ปลอดภัย |
| SequenceEqual (LINQ) | sb1.ToString().SequenceEqual(sb2.ToString()) | ไม่สร้างสตริงกลาง (แต่ยัง ToString) |
| Custom Extension | เขียน Extension Method เองเปรียบเทียบ Char โดยตรง | ประสิทธิภาพดีที่สุด (No Allocation) |
Extension Method สำหรับเปรียบเทียบโดยไม่สร้าง String ใหม่
public static class StringBuilderExtensions
{
public static bool ContentEquals(this StringBuilder sb1, StringBuilder sb2)
{
if (ReferenceEquals(sb1, sb2)) return true;
if (sb1 is null || sb2 is null) return false;
if (sb1.Length != sb2.Length) return false;
for (int i = 0; i < sb1.Length; i++)
{
if (sb1[i] != sb2[i]) return false;
}
return true;
}
}
// ใช้งาน
var sb1 = new StringBuilder("Hello");
var sb2 = new StringBuilder("Hello");
Console.WriteLine(sb1.ContentEquals(sb2)); // True
ข้อสังเกตสำคัญ
- StringBuilder.Equals(object) = Reference Equality (Default Object Behavior)
- ไม่มี Override Equals สำหรับ Value Comparison
- ต้องแปลงเป็น String ก่อนเปรียบเทียบค่า (
ToString()) - สำหรับ Performance Critical ให้เขียน Extension Method เปรียบเทียบ Char Array โดยตรง
StringBuilderเป็น Mutable Class ใช้สำหรับสร้างสตริงอย่างมีประสิทธิภาพ