Trong C#, string (alias của System.String) là một **reference type** nhưng được thiết kế để so sánh **giá trị** (value semantics) khi sử dụng phương thức Equals() hoặc toán tử ==.
Ví dụ 1: Hai chuỗi giống nhau
using System;
public class Demo
{
public static void Main(string[] args)
{
string str1 = "John";
string str2 = "John";
Console.WriteLine("String 1 = " + str1);
Console.WriteLine("String 2 = " + str2);
Console.WriteLine("String 1 bằng String 2: {0}", str1.Equals(str2));
}
}
Kết quả
String 1 = John String 2 = John String 1 bằng String 2: True
Ví dụ 2: Hai chuỗi khác nhau
using System;
public class Demo
{
public static void Main(string[] args)
{
string str1 = "Tom";
string str2 = "Kevin";
Console.WriteLine("String 1 = " + str1);
Console.WriteLine("String 2 = " + str2);
Console.WriteLine("String 1 bằng String 2: {0}", str1.Equals(str2));
}
}
Kết quả
String 1 = Tom String 2 = Kevin String 1 bằng String 2: False
Các cách so sánh chuỗi trong C#
| Phương pháp | Cú pháp | So sánh | Null-safe |
|---|---|---|---|
| Instance Equals | str1.Equals(str2) |
Giá trị | Cần check null trước |
| Static Equals | string.Equals(str1, str2) |
Giá trị | Có (an toàn null) |
| Toán tử == | str1 == str2 |
Giá trị | Có |
| StringComparison | str1.Equals(str2, StringComparison.OrdinalIgnoreCase) |
Giá trị (có tùy chọn) | Cần check null |
| Compare | string.Compare(str1, str2) == 0 |
Giá trị (có culture) | Có |
Ví dụ các cách so sánh
string a = "Hello"; string b = "hello"; string c = null; Console.WriteLine(a.Equals(b)); // False (case-sensitive) Console.WriteLine(a.Equals(b, StringComparison.OrdinalIgnoreCase)); // True Console.WriteLine(string.Equals(a, b)); // False Console.WriteLine(string.Equals(a, b, StringComparison.OrdinalIgnoreCase)); // True Console.WriteLine(a == b); // False Console.WriteLine(string.Compare(a, b, true) == 0); // True (ignore case) Console.WriteLine(string.Equals(c, a)); // False (an toàn null)
String Interning (Tối ưu hóa bộ nhớ)
string s1 = "Hello";
string s2 = "Hello";
string s3 = String.Intern("Hello");
Console.WriteLine(ReferenceEquals(s1, s2)); // True - string literal được intern
Console.WriteLine(ReferenceEquals(s1, s3)); // True
// String builder tạo chuỗi mới
StringBuilder sb = new StringBuilder();
sb.Append("Hel").Append("lo");
string s4 = sb.ToString();
Console.WriteLine(ReferenceEquals(s1, s4)); // False - đối tượng khác
Console.WriteLine(s1.Equals(s4)); // True - giá trị giống nhau
Best Practices
- Dùng
string.Equals(a, b)hoặca == b- an toàn null, dễ đọc - Dùng
StringComparison.Ordinalcho so sánh chính xác (file path, config, ID...) - Dùng
StringComparison.OrdinalIgnoreCasecho case-insensitive - Tránh
StringComparison.CurrentCulturetrừ khi hiển thị cho user - Không dùng
ReferenceEqualscho string (trừ khi debug interning)
Lưu ý về null
string s1 = null; string s2 = "test"; // An toàn string.Equals(s1, s2); // False s1 == s2; // False // Ném NullReferenceException s1.Equals(s2); // LỖI - s1 là null