2016-01-26 85 views
28

我想知道如何比較兩個盒裝整數(可以是有符號或無符號)彼此是否相等。比較兩個整數對象是否相等,無論類型

例如,看看這個場景:

// 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) 

我難倒就如何可靠地比較盒裝整型這種方式。直到運行時我纔會知道它們是什麼,我不能將它們都投到long,因爲其中一個可能是ulong。我也不能將它們都轉換爲ulong,因爲可能是負面的。

我可以想出的最好的想法是隻是試錯法,直到找到一個常見的類型或者可以排除它們不相等,這不是一個理想的解決方案。

+1

'int3.Equals()'是不是真正的被覆蓋的'Equals',它的過載('等於(INT)''VS等於(對象)') – Rob

+0

你的意思 「但情況3失敗」? –

+0

[((object)(int)1).Equals(((object(ushort)1))yield false?](http:// stackoverflow。com/questions/25305393/why-does-objectint1-equalsobjectushort1-yield-false) –

回答

35

在第二種情況下,你實際上最終調用int.Equals(int),因爲ushort隱式轉換爲int。這個重載解析在編譯時執行。它在情況3中不可用,因爲編譯器只知道int5int6的類型爲object,所以它調用object.Equals(object) ...並且如果兩個對象的類型不同,那麼object.Equals將返回false是自然的。

可能使用動態類型在執行時執行相同類型的重載的 - 但你仍然有一個問題,如果你嘗試過這樣的:

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

這裏沒有重載會處理long,所以它會調用正常object.Equals

一種選擇是將值轉換爲decimal

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

這將處理比較ulonglong爲好。

我選擇了decimal,因爲它可以準確地表示每個基本整數類型的每個值。

0

整數是value類型。當你比較兩種整數類型時,compiller檢查它們的

對象是reference類型。當你比較兩個物體時,compiller檢查他們的參考文獻

有趣的部分是在這裏:

object int5 = (int)50505; 

Compiller同名但boxing操作,包裝值類型爲引用類型,並Equals會比較參考,並不值。

+1

問題中的措辭應該清楚,我知道價值和參考類型之間的差異,但實際上這根本不回答問題。 – caesay