7

Have I just forgotten the obvious, or is the "manual" comparer the best way to go?

Basically, I just want to compare the contents of type (small) byte-arrays. If all bytes match, the result should be true, otherwise false.

I was expecting to find that Array.Equals or Buffer.Equals would help.

Demonstration Code:

  var a = new byte[]{1, 2, 3, 4, 5};
  var b = new byte[]{1, 2, 3, 4, 5};
  Console.WriteLine(string.Format("== : {0}", (a == b)));
  Console.WriteLine(string.Format("Equals : {0}", a.Equals(b)));
  Console.WriteLine(string.Format("Buffer.Equals : {0}", Buffer.Equals(a, b)));
  Console.WriteLine(string.Format("Array.Equals = {0}", Array.Equals(a, b)));
  Console.WriteLine(string.Format("Manual_ArrayComparer = {0}", ArrayContentsEquals(a, b)));

Manual function:

/// <summary>Returns true if all elements of both byte-arrays are identical</summary>
public static bool ArrayContentsEquals(byte[] a, byte[] b, int length_to_compare = int.MaxValue)
{
  if (a == null || b == null) return false;
  if (Math.Min(a.Length, length_to_compare) != Math.Min(b.Length, length_to_compare)) return false;
  length_to_compare = Math.Min(a.Length, length_to_compare);
  for (int i = 0; i < length_to_compare; i++) if (a[i] != b[i]) return false;
  return true;
}
3
  • Array.Equals, Buffer.Equals etc are really the same thing: Object.Equals. As both Array and Bufferderive from Object, you're just calling the static Object.Equals method using a derived type name. This will check reference equality. Commented Mar 5, 2015 at 11:54
  • I've just seen the SequenceEqual option in this question Commented Mar 5, 2015 at 11:55
  • 1
    best isn't a good metric :-) Speed, compatibility, shortness of writing, easiness of comprehension, ... Commented Mar 5, 2015 at 12:13

1 Answer 1

17

You are looking for SequenceEqual method.

a.SequenceEqual(b);

Determines whether two sequences are equal by comparing the elements by using the default equality comparer for their type.

Sign up to request clarification or add additional context in comments.

5 Comments

It should be noted that SequenceEqual seems to be implemented in a way to just iterate over both enumerations and compare element by element, and return false if one enumeration ends sooner than the other. If many comparisons are made between many arrays of different length, checking whether the lengths match first would be a more sensible approach.
Thanks - it is certainly "one" of the things I'd missed (before I looked at the answers to related questions) - Not sure if has a "shortcut-to-false" option if the byte[] arrays are different lengths... But at least I've got something to look at. I wasn't sure If Buffer and Array implemented their own overload of the simple Object or not - hence the reason for checkin.
@Steven_W: "Not sure if has a "shortcut-to-false" option if the byte[] arrays are different lengths..." - well, I'm sure, I just checked what the actual assemblies do with ILSpy.
the reference is available over at referencesource.microsoft.com as well. Here's SequenceEqual
Although I've marked this as "the answer", I do also appreciate the additional comments such as the one by @xanatos - SequenceEqual was the inbuilt function that I'd missed, but the manual approach (and linked question) also have their merits, for clarity, speed, etc... In this case, I'm only comparing about 8 bytes (and not in a performance-critical section), so will probably stick with the manual approach - Thanks to all.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.