2010-12-28 21 views
6

Các MSDN Guidelines for Overloading Equals() and Operator == nhà nước:Trọng toán tử == trong các loại phi bất biến

Theo mặc định, các nhà điều hành == kiểm tra cho bình đẳng tham khảo bằng cách xác định nếu hai tài liệu tham khảo cho thấy cùng một đối tượng , vì vậy các loại tài liệu tham khảo không cần để thực hiện toán tử == để nhận chức năng này. Khi một loại là bất biến, có nghĩa là dữ liệu chứa trong trường hợp không thể thay đổi, quá tải toán tử == để so sánh bình đẳng giá trị thay vì bình đẳng tham khảo có thể hữu ích bởi vì, như các đối tượng bất biến, họ có thể được coi là miễn là chúng có cùng giá trị. Ghi đè nhà điều hành == trong các loại không thay đổi là không được khuyến nghị.

Có ai giải thích lý do đằng sau chữ in đậm không?

CHỈNH SỬA - Đồng thời, hướng dẫn này có liên quan đến nhà điều hành == không, hoặc có nghĩa là đối với phương pháp Equals không?

Trả lời

16

Suy đoán được giáo dục của tôi là làm cho mọi thứ hoạt động như các kiểu .NET được tạo sẵn, cụ thể là == sẽ hoạt động như bình đẳng tham chiếu nếu có thể và Equals sẽ hoạt động như bình đẳng giá trị khi có thể. Hãy xem xét sự khác biệt thực sự giữa ==Equals:

object myObj = new Integer(4); 
object myObj2 = new Integer(4); 

//Note that == is only called if the ref'd objects are cast as a type 
//overloading it. 
myObj == myObj2; //False (???) 
myObj.Equals(myObj2); //True (This call is virtual) 

//Set the references equal to each other -- note that the operator== 
//comparison now works. 
myObj2 = myObj; 
myObj == myObj2; //True 
myObj.Equals(myObj2); //True 

Hành vi này là tất nhiên không phù hợp và khó hiểu, đặc biệt là các lập trình viên mới - nhưng nó cho thấy sự khác biệt giữa sự so sánh tài liệu tham khảo và so sánh giá trị.

Nếu bạn làm theo hướng dẫn MSDN này, bạn đang làm theo hướng dẫn được thực hiện bởi các lớp quan trọng như chuỗi. Về cơ bản - nếu so sánh sử dụng == thành công, lập trình viên biết rằng so sánh đó sẽ luôn thành công, miễn là các tham chiếu liên quan không được gán cho các đối tượng mới. Các lập trình viên không bao giờ cần phải lo lắng về nội dung của các đối tượng là khác nhau, vì họ không bao giờ sẽ khác nhau:

//Mutable type 
var mutable1 = new Mutable(1); 
var mutable2 = mutable1; 
mutable1 == mutable2; //true 
mutable1.MutateToSomethingElse(56); 
mutable1 == mutable2; //still true, even after modification 
//This is consistent with the framework. (Because the references are the same, 
//reference and value equality are the same.) Consider if == were overloaded, 
//and there was a difference between reference and value equality: 

var mutable1 = new Mutable(1); 
var mutable2 = new Mutable(1); 
mutable1 == mutable2; //true 
mutable1.MutateToSomethingElse(56); 
mutable1 == mutable2; //oops -- not true anymore 
//This is inconsistent with, say, "string", because it cannot mutate. 

Nó nắm để mà không có lý do kỹ thuật thực sự cho phương châm - nó chỉ là để duy trì phù hợp với phần còn lại của các lớp trong khung công tác.

+1

+1 đây rõ ràng là câu trả lời –

+0

Rất tốt nghĩ ra câu trả lời tốt. – jason

0

Giả sử bạn có loại có thể thay đổi A và bạn tạo tập hợp hoặc đối tượng thuộc loại A. Thêm đối tượng vào tập hợp sẽ không thành công nếu đối tượng này đã tồn tại trong tập hợp.

Bây giờ giả sử bạn thêm một đối tượng vào tập hợp, và sau đó bạn thay đổi các thuộc tính của nó để nó trở thành bằng một đối tượng khác trong tập hợp. Bạn đã tạo một trạng thái bất hợp pháp, trong đó có hai đối tượng trong tập hợp bằng nhau.

+0

Nhưng sử dụng 'Bằng’ thay vì '== 'không khắc phục được sự cố này. –

+0

Một hướng dẫn khác là luôn luôn ghi đè '==' và 'Equals()' cùng nhau. Và 'getHashCoe()' nữa. –

+0

Thực ra nó - Bình đẳng là khác nhau về mặt ngữ nghĩa. Đọc tài liệu cho cả hai để xem sự khác biệt. – TomTom

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