2012-04-03 34 views
3

這讓我拉我的頭髮幾天:ValueType的數組不喜歡object.Equals?

byte[] _A = new byte[64]; 
// Fill _A with some meaningful, valid data. 

byte[] _B = new byte[_A.Length]; 
_A.CopyTo(_B, 0); 

if(!_A.Equals(_B)) { 
    throw new WtfException(
     "It appears object.Equals doesn't work on arrays of value types..."); 
} 

是的,這將引發WtfException。我花了幾天時間才注意到。 byteValueType。但是,byte[]System.Array,它是一個參考類型。根據.NET文檔:

Equals的默認實現支持引用類型爲 的引用相等,以及值類型按位相等。參考 相等意味着被比較的對象引用指的是同一對象的 。按位相等意味着被比較的對象具有相同的二進制表示。

任何人都可以幫忙嗎?

回答

3

_A和_B不是對同一個數組的引用。因此,它們不是平等的。你需要做這樣的事情:

private static bool ValueTypeArraysAreEqual(Array p_lhs, Array p_rhs) { 
if(p_lhs == null) { 
return p_rhs == null; 
} 
if(p_rhs == null) { 
return false; 
} 
if(p_lhs.Length != p_rhs.Length) { 
return false; 
} 
return Parallel.For(0, p_lhs.Length, (_lcv, loopState) => { 
if(!p_lhs.GetValue(_lcv).Equals(p_rhs.GetValue(_lcv))) { 
loopState.Break(); 
} 
}).IsCompleted; 
} 

你可以在循環中使用object.Equal,因爲你可以比較Loop包含的ValueTypes。使用System.Threading.Tasks.Parallel可以幫助我更快地移動事物。 Parallel.For返回一個結構,告訴你該循環是否被暫停。如果你從來沒有停止loopState.Break循環,那麼他們都匹配。如果出於某種原因不能使用Parallel.For,只需執行返回false的for循環;

2

數組使用引用相等,而不是成員相等。所以這表現得如預期。

如果需要,您可以使用SequenceEqual來實現成員等式。

5

您正在比較引用類型(數組)而不是數值類型。 _A和_B確實不同 - 它們是恰好包含相同值的兩個不同數組。

2

該文檔正好解釋了您所看到的內容。可怕的類比警告:僅僅因爲兩張紙上寫有相同的數字,並不能使它們成爲同一張紙。

您可能對SequenceEqual感興趣,當僅有兩個序列按相同順序包含相同的值時,將返回true