Có một số điều đang diễn ra. Thứ nhất, trong ví dụ này:
string s1 = "a";
string s2 = "a";
Console.WriteLine(s1 == s2);
Bạn cho rằng:
Cả hai đều là tài liệu tham khảo đối tượng khác nhau.
Điều này không đúng do thực hiện chuỗi.s1
và s2
là các tham chiếu đến cùng một đối tượng. Đặc tả C# đảm bảo rằng - từ mục 2.4.4.5 của đặc điểm kỹ thuật C# 4:
Khi hai hay nhiều chuỗi ký tự tương đương theo toán tử bình đẳng chuỗi (§7.10.7) xuất hiện trong cùng một chương trình, các chuỗi ký tự này tham chiếu đến cùng một cá thể chuỗi.
Vì vậy, trong trường hợp đặc biệt này, bạn sẽ vẫn nhận được "true" ngay cả khi bạn in object.ReferenceEquals(s1, s2)
, hoặc nếu bạn đã làm cho nó sử dụng một so sánh sắc tham khảo đúng với ==
:
object s1 = "a";
object s2 = "a";
Console.WriteLine(s1 == s2); // Still prints True due to string literal interning
Tuy nhiên, ngay cả khi những tài liệu này là tham chiếu đến các đối tượng riêng biệt, ==
là bị quá tải cho string
. Quá tải là một quyết định biên dịch - việc triển khai sử dụng phụ thuộc vào các loại biên dịch của các toán hạng. Ví dụ:
string a = new string('x', 1);
string b = new string('x', 1);
Console.WriteLine(a == b); // Uses string's implementation, prints True
object c = a;
object d = b;
Console.WriteLine(c == d); // Reference identity comparison, prints False
So sánh điều đó với object.Equals(object)
là phương pháp ảo. Khi điều đó xảy ra, String
quá tải phương pháp này cũng như, nhưng quan trọng là nó ghi đè lên. Vì vậy, nếu chúng ta thay đổi mã của chúng tôi để:
string a = new string('x', 1);
string b = new string('x', 1);
Console.WriteLine(a.Equals((object) b));
object c = a;
object d = b;
Console.WriteLine(c.Equals(d));
... sau đó cả hai phương pháp gọi trong mã biên dịch sẽ chỉ đơn giản là để object.Equals(object)
, nhưng họ sẽ vẫn cả in Đúng vì đa hình: thực hiện trong String
sẽ được sử dụng.
Đây là những gì một cuộc gọi đến quá tải phương pháp sẽ trông như thế:
string a = new string('x', 1);
string b = new string('x', 1);
Console.WriteLine(a.Equals(b)); // Calls string.Equals(string)
Hai câu hỏi: tại sao lại chọn 'd' thành' đối tượng', vì nó đã là một đối tượng? Ngoài ra, trong phần 'a Equals b', tôi sẽ gọi cả override đối tượng và chuỗi quá tải, do đó, rõ ràng hơn sự khác biệt là gì. – doekman
@doekman: 1) Có, tôi không cần dàn diễn viên trong trường hợp đó. 2) Không chắc chắn những gì bạn có ý nghĩa. –
Ý tôi là: xem anwer cuối cùng. Tôi đã không trực tiếp nhận được lời giải thích của bạn về quá tải/ghi đè .... – doekman