In .NET, arrays are only equal to another if they are the same array object. Thus, two different arrays that have the same contents are not considered equal:
int[] x = new int[] { 1, 2 }; int[] y = new int[] { 1, 2 }; Console.WriteLine(x == y);
To check equality based on content, you can use Enumerable.SequenceEqual
:
Console.WriteLine(x.SequenceEqual(y)); // true
Of course, this will not help you when trying to use Enumerable.Except
, since the default equality Enumerable.Except
will be used, which checks only for equality (and since each array is uneven for any other array except itself ...).
Thus, the solution will use a different overload and provide a custom IEqualityComparer
that compares arrays based on their contents.
public class IntArrayEqualityComparer : IEqualityComparer<int[]> { public bool Equals(int[] a, int[] b) { return a.SequenceEqual(b); } public int GetHashCode(int[] a) { return a.Sum(); } }
Unfortunately, simply delegating SequenceEqual
not enough. We also need to provide an implementation of GetHashCode
for this. As a simple solution, we can use the sum of the numbers in the array here. Usually we would like to provide a strong hash function that talks a lot about the content, but since we use this hash function to call Except
, we can use something simple here. (In general, we would also like to avoid creating a hash value from a mutable object)
And when using this equality comparator, we correctly filter duplicate arrays:
var c = a.Except(b, new IntArrayEqualityComparer());