ValueTypes arrays don't like object.Equals?

This made me pull my hair out for a couple of days:

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...");
}

      

Yes, it throws out WtfException

. It took me a few days to notice. byte

is ValueType

. However, byte[]

is System.Array

, which is a reference type. According to the .NET documenation:

The standard implementation of Equals supports reference equality for reference types and bitwise equality for value types. Help equality means that the object references that are being compared refer to the same object. Bitwise equality means that the objects being compared have the same binary representation.

Does anyone help?

+3


source to share


4 answers


_A and _B are not references to the same array. Thus, they are not equal. You need to do something like this:

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;
}

      



you can use object.Equal in loops because you can compare the ValueTypes that the Loop contains. Using System.Threading.Tasks.Parallel helps me move things around a little faster. Parallel.For returns a structure that tells you if the loop has stopped. If you've never stopped a loop with loopState.Break, they are all the same. If for some reason you cannot use Parallel.For, just do a for loop that returns false;

+3


source


You are comparing reference types (arrays), not value types. _A and _B are really different - they are two different arrays that contain the same values.



+5


source


The array uses reference equality, not member equality. So this behaves as expected.

You can use SequenceEqual

for equality in order if you like.

+2


source


This documentation explains exactly what you are seeing. A warning against a formidable analogy: just because the same numbers are written on two sheets of paper, they don't make them the same sheet of paper.

You may be wondering SequenceEqual

which will return true

if and only if two sequences contain the same values ​​in the same order.

+2


source







All Articles