2012-03-19 20 views
8
 string s1 = "t"; 
     string s2 = 't'.ToString();   

     Console.WriteLine(s1.Equals(s2)); // returning true 
     Console.WriteLine(object.Equals(s1, s2)); // returning true 

Đây là kết quả tương tự. Bây giờ khi tôi đang sử dụng StringBuilder nó không trả về cùng một giá trị. Lý do bên dưới là gì?Tại sao object.Equals và instanceobject.Equals không giống nhau

 StringBuilder s1 = new StringBuilder(); 
     StringBuilder s2 = new StringBuilder(); 

     Console.WriteLine(s1.Equals(s2)); // returning true 
     Console.WriteLine(object.Equals(s1, s2)); // returning false 

Edit1: Câu hỏi trên của tôi được trả lời bên dưới. Nhưng trong cuộc thảo luận này những gì chúng ta tìm ra StringBuilder không có bất kỳ phương thức override Equals nào trong việc thực thi nó. Vì vậy, khi chúng ta gọi StringBuilder.Equals nó thực sự đi đến Object.Equals. Vì vậy, nếu ai đó gọi StringBuilder.Equals và S1.Equals (S2) thì kết quả sẽ khác.

+1

Tốt bắt! Tóm lại, 'StringBuilder' dường như quên ghi đè' Equals (object) '. Có vẻ như ngược trực giác để có 'Equals (StringBuilder)' có hành vi khác nhau từ 'Equals (object)'. – leppie

Trả lời

7

String.Equals() được ghi đè trong C# sao cho các chuỗi giống hệt nhau thực tế là Equal() khi ghi đè Equal() được xác định trên string được sử dụng.

Nếu bạn đang so sánh string literals (không phải trường hợp trong ví dụ của bạn), cần lưu ý rằng các chuỗi ký tự giống hệt nhau là interned ... có nghĩa là, các chuỗi giống nhau sống ở cùng một địa chỉ cũng sẽ bằng tham chiếu (ví dụ: đối tượng .Equals() hoặc s1.ReferenceEquals (s2)) cũng như theo giá trị.

StringBuilder cung cấp tình trạng quá tải đến Equals() nhận StringBuilder làm tham số (nghĩa là s1.Equals(s2) sẽ gọi quá tải đó thay vì gọi object.Equals(object obj)).

http://msdn.microsoft.com/en-us/library/system.text.stringbuilder.equals.aspx

StringBuilder.Equals() là ...

đúng nếu trường hợp này và sb có chuỗi bằng nhau, năng lực, và giá trị MaxCapacity; ngược lại, sai.

object.Equals() sử dụng số static Equals() defined on object, chỉ kiểm tra tính bình đẳng tham chiếu (nếu đã vượt qua lớp) hoặc value equality (nếu đã chuyển cấu trúc).

Vì vậy, trong bản tóm tắt

string s1 = "t"; 
string s2 = 't'.ToString();   

Console.WriteLine(s1.Equals(s2)); // true because both reference equality (interned strings) and value equality (string overrides Equals()) 
Console.WriteLine(object.Equals(s1, s2)); // true because of reference equality (interned strings) 

StringBuilder s1 = new StringBuilder(); 
StringBuilder s2 = new StringBuilder(); 

Console.WriteLine(s1.Equals(s2)); // true because StringBuilder.Equals() overloaded 
Console.WriteLine(object.Equals(s1, s2)); // false because the two StringBuilder instances have different addresses (references not equal) 
+5

Về mặt kỹ thuật StringBuilder chỉ overloads Bằng phương thức mà không ghi đè đối tượng ảo.Equals (đối tượng). Đây là lý do tại sao hai phương thức hoạt động khác nhau. Tôi tự hỏi nếu họ quên làm điều đó trong NET1.0 và không muốn giới thiệu một sự thay đổi đột phá? – alexm

+0

@alexm: Tốt bắt. Tôi đã không nhận thấy điều đó trước đây. Đã cập nhật câu trả lời của tôi. –

+0

Thaks Eric cho lời giải thích tốt đẹp. Nếu tôi tạo một bản tóm tắt nhỏ ra khỏi nó: object.Equals sẽ kiểm tra tham chiếu hoặc giá trị phụ thuộc vào kiểu đối tượng đầu vào. Trong khi String và StringBuilder có phương thức Equal overload/overridden của riêng nó sẽ hoạt động theo cách thực hiện của chúng. Nêu tôi sai vui long chân chỉnh tôi. –

1

Các generic Equals method so sánh tài liệu tham khảo của hai đối tượng để xem họ có tham khảo bình đẳng đối với các loại tài liệu tham khảo như StringBuilder. Đối với các loại giá trị và string hoạt động như một loại giá trị (không thay đổi), nó thực hiện so sánh bit bit (xác định xem biểu diễn nhị phân có giống nhau hay không). Tuy nhiên, chức năng này bị quá tải trong lớp StringBuilder.

Theo MSDN, phương pháp bình đẳng của StringBuilder sẽ trở thành sự thật nếu các tiêu chí sau cho cả hai đối tượng StringBuilder đều bình đẳng:

  • Chuỗi
  • Công suất
  • MaxCapacity

Như vậy, s1 và s2 trong ví dụ thứ hai không tham chiếu bình đẳng, nhưng vượt qua sự bình đẳng StringBuilder Equals tùy chỉnh dựa trên các tiêu chí vừa được đề cập.

+0

Chuỗi không phải là một loại giá trị. (Đây là một kiểu tham chiếu với ngữ nghĩa giá trị.) Http://stackoverflow.com/questions/1069155/is-string-a-value-type-or-a-reference-type –

+0

@BradleyGrainger, tôi biết nó không phải là về mặt kỹ thuật là một loại giá trị, nhưng trong trường hợp này nó hoạt động giống nhau. Tôi sẽ cập nhật câu trả lời của tôi để làm rõ mặc dù. Cảm ơn. – Matt

1

Chuỗi cụ lớp Equals theo cách như vậy mà nó sẽ so sánh giá trị của chuỗi.

Hầu hết các trường hợp đối tượng, trừ khi chúng triển khai một loại so sánh khác, hãy kiểm tra xem đối tượng tham chiếu có giống nhau hay không.

Lưu ý rằng cũng có trường hợp hai hằng số chuỗi khác nhau chứa cùng giá trị chính xác ban đầu được gán cho cùng một tham chiếu đối tượng của trình biên dịch.

Các vấn đề liên quan