ValueTypes的数组不喜欢object.Equals?

时间:2012-04-03 08:47:07

标签: c# arrays

这让我把头发拉了几天:

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的默认实现支持引用相等   引用类型和值类型的按位相等。参考   等于意味着被比较的对象引用引用   同一个对象。按位相等意味着被比较的对象具有   相同的二进制表示。

有人可以帮忙吗?

4 个答案:

答案 0 :(得分:5)

您正在比较引用类型(数组)而不是值类型。 _A和_B确实不同 - 它们是两个碰巧包含相同值的不同数组。

答案 1 :(得分: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 :(得分:2)

数组使用引用相等,而不是成员相等。所以这表现得像预期的那样。

如果需要,可以使用SequenceEqual进行成员相等。

答案 3 :(得分:2)

该文档准确地解释了您所看到的内容。可怕的类比警告:只是因为两张纸都写有相同的数字,不会使它们成为同一张纸。

您可能会对SequenceEqual感兴趣,当且仅当两个序列包含相同顺序的相同值时,才会返回true