2012-03-22 43 views
15

Giả sử tôi xác định hai tuples:tuple == Lẫn lộn

Tuple<float, float, float, float> tuple1 = new Tuple<float, float, float, float>(1.0f, 2.0f, 3.0f, 4.0f); 
Tuple<float, float, float, float> tuple2 = new Tuple<float, float, float, float>(1.0f, 2.0f, 3.0f, 4.0f); 

Nếu tôi cố gắng để so sánh các bộ, tôi nhận được kết quả khác nhau

bool result1 = (tuple1 == tuple2); // FALSE 
bool result2 = tuple1.Equals(tuple2); // TRUE 

Tôi mong chờ cho cả các cuộc gọi đến trở thành sự thật. Chính xác là gì == so sánh?

+0

http://msdn.microsoft.com/en-us/library/53k8ybth.aspx –

Trả lời

31

Đối với Tuple, == đang so sánh các tham chiếu đối tượng vì nó không quá tải toán tử ==. Vì các đối tượng là tương đương, nhưng không phải cùng một cá thể cụ thể, Equals() trả lại true== trả lại false.

Nhiều loại không quá tải ==, một số loại muốn giữ sự khác biệt giữa Equals() cho tương đương và == để tham chiếu bình đẳng.

Bên cạnh đó, dựa vào == cho tương đương có thể dẫn đến một số weirdness:

public bool AreSame<T>(T first, T second) where T : class 
{ 
    return first == second; 
} 

Đoạn mã trên sẽ luôn luôn kiểm tra cho bình đẳng tham khảo vì một generic không bị giới hạn được coi là một object tại thời gian biên dịch, do đó nếu phương pháp này không phải là ảo, bạn sẽ nhận được phiên bản của đối tượng (ngay cả khi loại, chẳng hạn như string quá tải ==).

Do đó việc sử dụng này của đoạn code trên:

var x = "Hello"; 
var y = "H"; 

// doing concat to avoid string interring 
AreSame(x, y+"ello"); 

Vâng, các dây là tương đương, có Tstring, nhưng == chắc chắn sẽ phản đối của == kể từ chung chung là không bị giới hạn, do đó điều này sẽ trở false mặc dù cùng một mã với thông số rõ ràng string sẽ trả lại true.

+0

cám ơn tôi đã giả định rằng '==' và 'Equals' cơ bản giống nhau. Sự nhầm lẫn của tôi xuất phát từ các nguyên tắc quá tải của MSDN, http://msdn.microsoft.com/en-us/library/ms173147%28v=vs.80%29.aspx, trong đó '==' kiểm tra nhiều hơn chỉ là bình đẳng tham chiếu. – lumberjack4

+0

Nguyên tắc tốt nhất là kiểm tra tài liệu cho lớp để xem liệu chúng có thực hiện toán tử == hay không, và thậm chí sau đó, tôi thích sử dụng 'Equals()' cho phép kiểm tra tương đương bởi vì tìm kiếm một kiểm tra tương đương. Nhưng đó là tôi. –

+0

AFAICT, AreSame thậm chí sẽ không biên dịch. Tôi nhận được lỗi sau từ trình biên dịch: "Toán tử '==' không thể áp dụng cho toán hạng kiểu 'T' và 'T'" – RobSiklos

9

== đang so sánh các tham chiếu đối tượng. Lớp Tuple không quá tải nhà điều hành ==, vì vậy bạn cần sử dụng .Equals.

+0

Thực tiễn tốt nhất là ghi đè toán tử ==? Tôi giả định tất cả.Các lớp NET vượt qua toán tử ==. – lumberjack4

+0

Vì 'Tuple' là bất biến, có vẻ như một lập luận hợp lý có thể được thực hiện rằng lớp này sẽ là một ứng cử viên tốt để quá tải toán tử. Tuy nhiên, theo kinh nghiệm của tôi, kiểu duy nhất của lớp mà tôi từng mong đợi quá tải này nằm trong 'chuỗi' hoặc các kiểu nguyên thủy khác như' DateTime', 'TimeSpan', v.v. –

9

== cho Tuple sẽ chỉ thấy các tham chiếu và do đó bạn sẽ thấy rằng nó là sai.

PS: Đề xuất cách là để làm một cái gì đó như:

var tuple1 = Tuple.Create(1.0f, 2.0f, 3.0f, 4.0f) 
+0

Cảm ơn goodness n +1 cho rằng' .0f ', không có nó trình biên dịch đã được la hét cho' đôi để float chuyển đổi 'lỗi ... – bonCodigo

+2

Và một khi bạn thêm f, bạn có thể loại bỏ các '.0', tức là' 1f', '2f', vv – JotaBe