Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> C#

Kiểm tra hai StringBuilder bằng nhau trong C#

Trong C#, StringBuilder là một class đại diện cho chuỗi có thể thay đổi (mutable). Khi so sánh hai đối tượng StringBuilder, phương thức Equals() mặc định (kế thừa từ object) so sánh **tham chiếu** (reference equality), không so sánh nội dung chuỗi.

Ví dụ 1: So sánh tham chiếu

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 và strBuilder3 trỏ đến CÙNG MỘT ĐỐI TƯỢNG
        strBuilder2 = strBuilder3;

        Console.WriteLine("StringBuilder3 bằng StringBuilder2? = " + strBuilder3.Equals(strBuilder2));
    }
}

Kết quả

StringBuilder3 bằng StringBuilder2? = True

Ví dụ 2: Hai đối tượng khác nhau nhưng cùng nội dung

using System;
using System.Text;

public class Demo
{
    public static void Main(string[] args)
    {
        StringBuilder strBuilder1 = new StringBuilder("Jacob");
        StringBuilder strBuilder2 = new StringBuilder("Jacob");

        Console.WriteLine("StringBuilder1 bằng StringBuilder2? = " + strBuilder2.Equals(strBuilder1));
    }
}

Kết quả

StringBuilder1 bằng StringBuilder2? = True

Giải thích kỳ lạ?

⚠️ Lưu ý: Kết quả ví dụ 2 trả về True có thể do tối ưu hóa của runtime (string interning) hoặc bản in gốc có lỗi. Thực tế StringBuilder.Equals() **KHÔNG** so sánh nội dung chuỗi.

Thực tế: StringBuilder.Equals() so sánh tham chiếu

using System;
using System.Text;

public class Demo
{
    public static void Main()
    {
        StringBuilder sb1 = new StringBuilder("Hello");
        StringBuilder sb2 = new StringBuilder("Hello");
        StringBuilder sb3 = sb1; // Cùng tham chiếu

        Console.WriteLine("sb1.Equals(sb2): " + sb1.Equals(sb2)); // False - khác tham chiếu
        Console.WriteLine("sb1.Equals(sb3): " + sb1.Equals(sb3)); // True - cùng tham chiếu
        Console.WriteLine("ReferenceEquals(sb1, sb2): " + ReferenceEquals(sb1, sb2)); // False
        Console.WriteLine("ReferenceEquals(sb1, sb3): " + ReferenceEquals(sb1, sb3)); // True
    }
}

Kết quả thực tế

sb1.Equals(sb2): False
sb1.Equals(sb3): True
ReferenceEquals(sb1, sb2): False
ReferenceEquals(sb1, sb3): True

Cách đúng: So sánh nội dung StringBuilder

using System;
using System.Text;

public class Demo
{
    public static void Main()
    {
        StringBuilder sb1 = new StringBuilder("Hello World");
        StringBuilder sb2 = new StringBuilder("Hello World");
        StringBuilder sb3 = new StringBuilder("Hello");

        // Cách 1: Chuyển thành string rồi so sánh (khuyến nghị)
        bool equal1 = sb1.ToString() == sb2.ToString(); // True
        bool equal2 = sb1.ToString().Equals(sb2.ToString()); // True

        // Cách 2: So sánh thủ công (hiệu năng tốt hơn cho chuỗi lớn)
        bool equal3 = StringBuilderEquals(sb1, sb2);

        Console.WriteLine("ToString() == : " + equal1);
        Console.WriteLine("Equals(ToString()): " + equal2);
        Console.WriteLine("Manual compare: " + equal3);
    }

    // So sánh hiệu năng cao không cấp phát string mới
    public static bool StringBuilderEquals(StringBuilder a, StringBuilder b)
    {
        if (ReferenceEquals(a, b)) return true;
        if (a is null || b is null) return false;
        if (a.Length != b.Length) return false;
        
        for (int i = 0; i < a.Length; i++)
        {
            if (a[i] != b[i]) return false;
        }
        return true;
    }
}

So sánh StringBuilder vs String

Đặc điểm StringBuilder String
Kiểu Mutable (thay đổi được) Immutable (bất biến)
Equals() So sánh tham chiếu So sánh giá trị (nội dung)
== operator So sánh tham chiếu So sánh giá trị (overloaded)
So sánh nội dung sb1.ToString() == sb2.ToString() str1 == str2

Lưu ý

  • StringBuilder.Equals(object) không được override - dùng mặc định của object
  • Luôn dùng ToString() để so sánh nội dung
  • Cẩn thận với sb1 == sb2 - luôn so sánh tham chiếu
  • Để so sánh hiệu năng cao (tránh cấp phát string), tự viết phương thức so sánh char-by-char