2011-10-27 29 views
6

khi tôi cast int và float để đối tượng và so sánh chúng bình đẳng luôn luôn là sai. Tại sao?tại sao bằng không làm việc giống nhau khi các mục được đúc thành đối tượng?

 float f = 0.0f; 
     int i = 0; 
     Console.WriteLine(f.Equals(i)); // true 
     Console.WriteLine(i.Equals(f)); // false 
     Console.WriteLine(i == f); // true 
     Console.WriteLine("----------------"); 
     object obf = f; 
     object obi = i; 
     Console.WriteLine(obf.Equals(obi)); // false 
     Console.WriteLine(obi.Equals(obf)); // false 
     Console.WriteLine(obi == obf); // false 
     Console.WriteLine("----------------"); 

Cập nhật: này KHÔNG phải là trường hợp đối với cùng loại

 int i1 = 1; 
     int i2 = 1; 
     object oi1 = i1; 
     object oi2 = i2; 
     Console.WriteLine(oi1.Equals(oi2)); // true 
     Console.WriteLine(oi2.Equals(oi1)); // true 

Trả lời

10

Một float chỉ bằng float khác, và một int chỉ bằng int khác. Các đường chỉ được trở về true là những người:

Console.WriteLine(f.Equals(i)); 
Console.WriteLine(i == f); 

Trong cả hai trường hợp này, có một chuyển đổi ngầm về giá trị của i để float, vì vậy họ đang tương đương với:

Console.WriteLine(f.Equals((float) i)); 
Console.WriteLine((float) i == f); 

Những chuyển đổi này chỉ là chuyển đổi bình thường được yêu cầu để giải quyết quá tải các phương thức và toán tử.

Không ai trong số các phần còn lại của các dòng liên quan đến việc chuyển đổi tiềm ẩn, vì vậy họ đang so sánh hai loại khác nhau, trong đó đưa ra một kết quả của false ngay cả khi nó so sánh theo giá trị (đó là trường hợp với tất cả các Equals cuộc gọi). Đó là lý do tại sao sử dụng Equals trên giá trị int đóng hộp hiện trả lại true, bởi vì đó là so sánh hai giá trị cùng loại, theo giá trị.

Trong trường hợp này:

Console.WriteLine(obi == obf); 

nó thậm chí không cố gắng để so sánh giá trị số - nó so sánh các tài liệu tham khảo cho các đối tượng đóng hộp. Vì có hai tham chiếu khác nhau, kết quả là false - và sẽ là ngay cả khi cả hai giá trị đều thuộc loại int.

+0

chuyển đổi ngầm có được xử lý tại thời gian biên dịch không? –

+0

@CharlesLambert: Có. Hãy xem IL và bạn sẽ thấy nó đang được thực hiện. –

0

Khi bạn cast một loại giá trị cho đối tượng, nó thực sự bị đặt trong heap và == so sánh tài liệu tham khảo tại đó điểm, sẽ là sai. (Giản thể)

0

Equals so sánh địa chỉ của tham chiếu đối tượng và hai số được lưu trữ ở các vị trí khác nhau. nếu bạn so sánh hai loại giá trị Bằng nhau hoạt động chính xác vì nó đã bị ghi đè cho float, int, string và các loại khác.

0

Vì chúng được gán cho các ô ghi nhớ khác nhau. 2 đối tượng là = chỉ khi chúng là cùng một đối tượng. Trong phao và phần int bạn nhận được một sự thật khi bạn kiểm tra 2 biến vì thời gian chạy kiểm tra giá trị của chúng. đó là tất cả!

1

Khi bạn đã tuyên bố hai đối tượng họ tham chiếu đến một vị trí bộ nhớ khác nhau:

object obf = f;   // this simplified as new float(f) 
object obi = i;   // this simplified as new int(i) 

nhưng thử ra sau, hãy cho một đối tượng tham chiếu đến một khác:

obf = obi; 
Console.WriteLine(obf.Equals(obi)); 

MSDN, Object.Equals Method

Việc triển khai mặc định bằng Equals hỗ trợ bình đẳng tham chiếu cho loại tham chiếu và độ cân bằng bit đối với các loại giá trị. Tham chiếu bình đẳng có nghĩa là các tham chiếu đối tượng được so sánh tham khảo cùng một đối tượng. Độ cân bằng bitwise có nghĩa là các đối tượng được so sánh có cùng biểu diễn nhị phân.

3

Những người khác đã giải thích lý do tại sao == không hoạt động như mong đợi trên đối tượng của bạn.

Về sửa đổi của bạn: oi1.Equals(oi2) công trình vì Equals là một hàm ảo và, do đó, Int32.Equals(object) được gọi, mà trở lại giá trị được định nghĩa như sau:

đúng nếu obj là một thể hiện của Int32 và bình đẳng giá trị của cá thể này; nếu không, false.

Điều này cũng giải thích tại sao obi.Equals(obf)) trả về false: obf không phải là phiên bản của Int32.

1

Để hiểu thêm về những gì xảy ra khi bạn hộp các loại giá trị, Shivprasad mô tả này khá ngắn gọn ở đây:

Boxing and Unboxing

Vì bạn đang đấm bốc các loại giá trị cho các đối tượng, bạn đang thực hiện bình đẳng tham khảo. Vì giờ đây chúng nằm ở các vị trí bộ nhớ khác nhau trong ví dụ của bạn, sẽ trả về false.

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