Sven
Sven

Reputation: 2889

Different results for comparing Array[][] with SequenceEqual() and custom method

can someone explain me why I do get different results?

bool result = true;
for (int row = 0; row < State.Rows; row++)
{
    for (int col = 0; col < State.Cols; col++)
    {
         if (map[row][col] != other.map[row][col])
       //if (!map[row][col].Equals(other.map[row][col]))
             result = false;
    }
}
bool sequenceEqual = map.SequenceEqual(other.map);

//result = true
//sequenceEqual = false

I overwrote Equals(), GetHashCode(), == and != for the type to be compared. I also tried the CollectionComparer from this answer, and got the same result.

Upvotes: 1

Views: 1024

Answers (2)

Etienne de Martel
Etienne de Martel

Reputation: 36852

They're not equivalent.

SequenceEqual uses Equals for every element of a sequence. Since map is a two dimensional array, each "element" is actually a row, and that means that it's the Equals method of Array that ends up being called.

Your method compares each element directly using !=, which is what you want.

A solution would to supply a custom equality comparer to SequenceEquals. Said comparer would then call SequenceEquals again.

Upvotes: 4

Jon
Jon

Reputation: 437386

Completely rewritten answer

First of all, the two ways to compare do entirely different things.

The manual comparison:

  • compares all Rows * Cols items in your array
  • compares using reference equality (unless the item type overrides == and !=)

The SequenceEqual comparison:

  • compares only items directly in each array; this means it compares Rows arrays with other arrays!
  • compares by calling object.Equals

The result discrepancy stems from the fact that SequenceEqual boils down to:

if(!oneArray.Equals(anotherArray)) {
    return false;
}

That's a reference equality check. Which means that unless map and other.map are arrays of reference-identical sub-arrays, SequenceEqual will return false.

Live proof.

Upvotes: 2

Related Questions