2016-01-26 16 views
28

Tôi tự hỏi làm thế nào bạn có thể so sánh hai số nguyên đóng hộp (hoặc có thể được ký hoặc không ký) với nhau để bình đẳng.So sánh hai đối tượng số nguyên cho sự bình đẳng bất kể loại

Ví dụ, hãy nhìn vào kịch bản này:

// case #1 
object int1 = (int)50505; 
object int2 = (int)50505; 
bool success12 = int1.Equals(int2); // this is true. (pass) 

// case #2 
int int3 = (int)50505; 
ushort int4 = (ushort)50505; 
bool success34 = int3.Equals(int4); // this is also true. (pass) 

// case #3 
object int5 = (int)50505; 
object int6 = (ushort)50505; 
bool success56 = int5.Equals(int6); // this is false. (fail) 

Tôi đang bối rối về cách đáng tin cậy so sánh các loại nguyên đóng hộp theo cách này. Tôi sẽ không biết chúng là gì cho đến khi thời gian chạy, và tôi không thể bỏ cả hai đến long, bởi vì người ta có thể là ulong. Tôi cũng không thể chuyển đổi cả hai thành ulong bởi vì người dùng có thể là số âm.

Ý tưởng hay nhất mà tôi có thể đưa ra là chỉ thử nghiệm và đưa ra lỗi cho đến khi tôi có thể tìm thấy loại phổ biến hoặc có thể loại trừ chúng không bằng nhau, không phải là giải pháp lý tưởng.

+1

'int3.Equals()' không thực sự là overriden 'Equals', nó là một quá tải (' Equals (int) 'vs' Equals (object) ') – Rob

+0

Bạn có nghĩa là" nhưng trường hợp 3 thất bại "? –

+0

Có thể trùng lặp của [Tại sao ((đối tượng) (int) 1) .Equals (((đối tượng) (ushort) 1)) sản lượng sai?] (Http: // stackoverflow.com/questions/25305393/why-does-objectint1-equalsobjectushort1-yield-false) –

Trả lời

35

Trong trường hợp 2, bạn thực sự kết thúc cuộc gọi int.Equals(int), bởi vì ushort có thể chuyển đổi hoàn toàn thành int. Độ phân giải quá tải này được thực hiện tại thời gian biên dịch. Nó không có sẵn trong trường hợp 3 vì trình biên dịch chỉ biết loại int5int6object, vì vậy nó gọi object.Equals(object) ... và tự nhiên là object.Equals sẽ trả lại false nếu các loại của hai đối tượng khác nhau.

Bạn thể sử dụng gõ động để thực hiện cùng một loại có độ phân giải quá tải ở thời gian thực hiện - nhưng bạn vẫn muốn có một vấn đề nếu bạn đã cố gắng một cái gì đó như:

dynamic x = 10; 
dynamic y = (long) 10; 
Console.WriteLine(x.Equals(y)); // False 

Ở đây không có tình trạng quá tải mà sẽ xử lý long, vì vậy nó sẽ gọi số bình thường là object.Equals.

Một lựa chọn là để chuyển đổi các giá trị để decimal:

object x = (int) 10; 
object y = (long) 10; 
decimal xd = Convert.ToDecimal(x); 
decimal yd = Convert.ToDecimal(y); 
Console.WriteLine(xd == yd); 

này sẽ xử lý so sánh ulong với long là tốt.

Tôi đã chọn decimal vì nó có thể thể hiện chính xác mọi giá trị của mọi loại số nguyên nguyên thủy.

0

Số nguyên là loại value. Khi bạn so sánh hai loại số nguyên, trình biên dịch sẽ kiểm tra các giá trị của chúng.

Đối tượng là loại reference. Khi bạn so sánh hai đối tượng, trình biên dịch sẽ kiểm tra tài liệu của chúng tôi.

Phần thú vị là ở đây:

object int5 = (int)50505; 

Compiller perfoms boxing hoạt động, kết thúc tốt đẹp kiểu giá trị vào loại tài liệu tham khảo, và Equals sẽ so sánh tài liệu tham khảo, không phải giá trị.

+1

Nó phải được rõ ràng bởi các từ ngữ trong câu hỏi mà tôi biết sự khác biệt giữa giá trị và các loại tài liệu tham khảo, điều này không trả lời câu hỏi ở tất cả, thực sự. – caesay

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