21 thoughts on “Comparing arrays in C#

  1. Totally silly … I’ve run into all kinds of silly things like that, especially with their data structures. MS needs to sweat the details more on stuff like this, and worry a little less about all the frameworks built on this stuff.

  2. What if you compare the hashcode? that would be an ideal comparison, no?

  3. Hi LikeNoOther,

    Nice idea, but unfortunately they didn’t override the GetHashCode method in the array class. The default Object.GetHashCode implementation will be used instead which returns the sync block index of the object instance. Net effect will be the same as doing Object.Equals – different instances will not be considered equal even if they contain the same data.

    Good try though. 🙂

    Tatham

  4. 1- I agree with MS designers not overriding Array.Equals as it’s supposed to provide “value-like” behaviour. As a design best practice we should be consistent around == and != operators and also overriding Object.Equals method. BUT, I do 100% agree framework is missing something like Array.CompareContent!

    2- “memcpy” is already being used internally by System.Buffer. and perhaps MS folks would use “memcmp” internally easing Array.CompareContent implementation, BUT exposing such methods has issues with OO paradigm IMO, and higher level approaches are okay with almost same performance.

    3- as Taham said hash-value comparison won’t help work as Array doesn’t implement content-based hash generation. however, not a good idea generating hash-value in the sake of content comparison – performance issues in particular.

    Well, don’t understand why MS guys haven’t added such a helper method since even the very first version! 😦

  5. From System.Linq:

    Enumerable.SequenceEqual();

    or

    Console.WriteLine(new byte[] {1,2,3}.SequenceEqual(new byte[] {1,2,3}));

  6. If you are not using Linq
    Pleas try

    Convert.ToBase64String(array1)==Convert.ToBase64String(array2)

  7. There are two things wrong with your method:

    1. You can’t have both static and override modifiers on the same method – I presume this was a typo;

    2. Your method only works for vectors; multi-dimensional arrays would take a lot more effort.

  8. Hi,
    This technique is gud for me to compare to byte[] arrays.

    Convert.ToBase64String(array1)==Convert.ToBase64String(array2)

    Thanks!!

  9. Microsoft is correct in their explanation. I think as you become more experienced with OO languages it will make more sense.

    However, I wanted to explain why some of the suggestions here should not be used.

    1: Convert.ToBase64String(array1)==Convert.ToBase64String(array2)
    The problems with this are as follows:
    a: You are always getting the worst possible performance out of this. Without first checking the lengths of the arrays to be sure they are equal then you will always end up processing both arrays entirely.
    b: Terrible runtime performance. You are iterating across all of array1 and array2 to convert them to strings, then iterating across both resulting strings to check equality. This will do twice as much work as just iterating through them and comparing the array byte values. Just because a method is provided by the runtime does not make it any faster than doing it manually(in most cases).
    c: Terrible memory use. Although the strings are only used for a moment, there is a price to pay for allocating them.

    I would write more but now I am tired of all of this.
    -Tim

  10. If you don’t want to create your own class, just use this helper method somewhere.

    private static bool CompareByteArrays(byte[] array1, byte[] array2)
    {
    if (array1.Length != array2.Length)
    return false;

    for (int i = 0; i < array1.Length; i++)
    if (array1[i] != array2[i])
    return false;

    return true;
    }

    Good luck!

    =D Kees

  11. public static bool ValueCompare(this T[] a, T[] b) where T: struct
    {
       if (a.Length != b.Length)
          return false;
       EqualityComparer q = EqualityComparer.Default;
       for (int i = 0; i < a.Length; i++)
          if (!q.Equals(a[i],b[i]))
             return false;
       return true;
    }

    1. The angle brackets for the generic argument T were stripped off my posting by your blog. It belongs after the function name “ValueCompare” and also after the EqualityComparer.

  12. ///
    /// Checks the equality of two arrays
    ///
    /// True if equals otherwise False
    public static bool Equals(this T[] array, T[] other)
    {
    if(array == null && other == null) return true;
    if(array == null || other == null)return false;
    if(array.Length != other.Length) return false;

    return !array.Where((t, i) => !Equals(t, other[i])).Any();
    }

  13. If you loop, you might as well loop in parallel.

    public static bool CompareArrays(T[] arrayA, T[] arrayB)
    {
    if (arrayA == arrayB) return true;
    if (arrayA == null || arrayB == null) return false;
    if (arrayA.Length != arrayB.Length) return false;

    var worked = Parallel.For(0, arrayA.Length, (i, loopState) =>
    {
    T itemA;
    //use the short circuit to set the item in the first part of the if, and compare in the second.
    if ((itemA = arrayA[i]) == null || !itemA.Equals(arrayB[i]))
    loopState.Stop();
    });

    //if successfully completed, then its correct. If broken out before the end, that means something wasnt right.
    return worked.IsCompleted;
    }

Comments are closed.