2012-04-11 60 views
19

thể trùng lặp:
Why ReferenceEquals and == operator behave different from EqualsTại sao cài đặt mặc định == không gọi Equals?

Việc thực hiện mặc định của == điều hành so sánh đối tượng bằng cách tham khảo. Vì vậy, khi bạn ghi đè Equals (hành vi mặc định giống nhau) bạn cũng phải chỉ định các toán tử ==!= để chúng gọi Equals (và làm cho nó trong mọi lớp phân cấp như các toán tử ==!= không phải là ảo).

Câu hỏi của tôi là tại sao lại như vậy? Tại sao ==!= so sánh các đối tượng bằng tham chiếu thay vì sử dụng Bằng? Tôi đoán có một lý do cho một điều cơ bản như vậy.

Cập nhật.

Để nhận xét: Tôi giả định == nên phụ thuộc vào Equals (nhưng không ngược lại) vì bạn có thể ghi đè Equals trong lớp cơ sở và sử dụng triển khai này trong các lớp dẫn xuất tự động. Nó sẽ không hoạt động nếu Equals đã sử dụng == khi triển khai, vì == không phải là ảo.

+2

Điều gì nên sử dụng 'Bằng’? – Oded

+1

Theo thiết kế, tương tự như Java, thực sự. –

+2

@JamesMichaelHare, quyết định thiết kế không đến từ đâu cả ... – SiberianGuy

Trả lời

5

Object.ReferenceEquals là thành viên static so sánh tham chiếu bình đẳng. Ngay cả các loại giá trị được đóng hộp trước khi được chuyển cho phương thức đó.

Điều gì về Equals, đó là phương pháp virtual, có nghĩa là nó cho phép người tiêu dùng ghi ghi đè một chức năng.

thực hiện Vì vậy, mặc định của == hành vi giả định so sánh mặc định (tham khảo) là ok cho bạn, nếu bạn cần một cái gì đó cụ thể, trong trường hợp này framework cung cấp cho bạn một phương pháp virtual, mà thể được ghi đè.

+1

Vì vậy, so sánh mặc định (tham chiếu) không ok cho tôi và tôi ghi đè Bằng nhưng tại sao tôi phải chỉ định == và! =? Usecase là gì khi tôi ghi đè Equals nhưng vẫn cần == và! = Để so sánh bằng tham chiếu? – SiberianGuy

+0

@Idsa: nếu bạn muốn như vậy, đó là một cách thực sự cho một mớ hỗn độn :). Phải có * một * cách so sánh trong (các) loại được chỉ định. Tôi nghĩ đó là ý tưởng ban đầu của nhà thiết kế khung. "Xác định tôi một cách để so sánh đối tượng này, và nó phải là cách duy nhất có thể, để tránh sự mơ hồ". – Tigran

8

Tôi tin rằng lý do chính là == là một tĩnh hành và có thể được gọi vào null đối tượng trong khi Equalsđòi hỏi một thể hiện.

Ví dụ:

Foo foo1 = null; 
Foo foo2 = null; 

Console.WriteLine(foo1 == foo2); // cannot use Equals 
+1

Nhưng Object.ReferenceEquals cũng là một phương pháp tĩnh – SiberianGuy

1

Các == đã được xung quanh và sử dụng để tham khảo từ C, và nó được tích hợp vào cú pháp ngôn ngữ thay vì phải trả lời về phương pháp gọi (Thậm chí nếu kết quả là như nhau cho cả hai).

Đơn giản, bởi vì C# không phải là Objective C :)

2

Các "lý do" là bởi vì đôi khi người ta cần phải biết nếu A là như nhau dụ như B như trái ngược với hay không mà họ chỉ đơn thuần là "bình đẳng "với nhau. Ví dụ, hai đối tượng bằng nhau có thể có ý nghĩa đối với hầu hết logic nghiệp vụ của bạn, tuy nhiên, bạn cũng có thể cần sử dụng một số tiện ích đồng thời thực hiện các hoạt động nguyên tử mà kết quả phụ thuộc vào nhận dạng đối tượng, chứ không phải bình đẳng .

+1

Nhưng có Object.ReferenceEquals cho trường hợp này – SiberianGuy

+2

Không có trong Java ... mà cũng được gắn thẻ cho câu hỏi này. –

+1

Vì vậy, câu hỏi thực sự là tại sao các nhà thiết kế C# làm điều này khi họ có tất cả lợi ích và kiến ​​thức về việc đã thấy Java trong thực tế trong một thập kỷ trước khi thiết kế ngôn ngữ C#. Tôi đoán là sự nhất quán. –

0

Trong Java, đôi khi rất tốt để nhanh chóng xác định xem hai số nhận dạng có bằng nhau hay không bằng cách so sánh các tham chiếu. == có địa điểm. Nếu bạn nhìn vào một phương pháp tạo ra phương pháp equals IDE, bạn thường sẽ thấy rằng so sánh đầu tiên được thực hiện là bình đẳng tham chiếu, sau khi tất cả, tại sao kiểm tra các trường nếu tham chiếu đối tượng giống nhau không?

0

Tôi sẽ gọi nó là một tính năng. Bằng cách tham chiếu hai đối tượng giống hệt nhau vẫn là hai đối tượng riêng biệt. Nếu bạn ghi đè Equals thì bạn có thể xác định xem hai đối tượng có giống nhau hay không. Ngay cả khi hai đối tượng là giống hệt nhau, tôi cũng có thể muốn kiểm tra nếu là cùng một đối tượng. Tôi thường có lý do để ghi đè bằng nhưng không bao giờ có nhu cầu ghi đè ==! = (Nhưng ngôn ngữ đó cung cấp tùy chọn đó).

Với chuỗi ghi đè == và tôi không thích nó. Mặc dù chuỗi là một kiểu tham chiếu, toán tử bình đẳng (== và! =) Được định nghĩa để so sánh các giá trị của các đối tượng chuỗi, không phải tham chiếu (7.9.7 toán tử bình đẳng chuỗi). Điều này làm cho thử nghiệm cho chuỗi bình đẳng trực quan hơn. Xem vấn đề này được giới thiệu. WPF ListBox Scroll to the bottom

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