Question

I am doing some byte[] comparisons.

I tried == but this is just like the base Equals, which:

byte[] a = {1,2,3};
byte[] b = {1,2,3};
bool equals = a == b; //false
equals = a.Equals(b); //false

I tried to add an extension method, but since the overloaded base class' Equals takes the same arguments, it goes to the base method rather to the extension, is there anyway I can use an Equals extension (wthout changing it's name...) or (even better) use == operator?

Here is what I actually have to Compare:

public static bool ContentEquals(this byte[] array, byte[] bytes)
{
    if (array == null || bytes == null) throw new ArgumentNullException();
    if( array.Length != bytes.Length) return false;
    for (int i = 0; i < array.Length; i++)
        if (array[i] != bytes[i]) return false;

    return true;
}
Was it helpful?

Solution

using System.Linq;

byte[] a = {1,2,3}; 
byte[] b = {1,2,3}; 
bool same = a.SequenceEqual(b);

OTHER TIPS

You certainly can't do operator overloading with extension methods. The reason it doesn't work for the Equals method is that if any method is applicable without using extension methods, that method will be chosen before extension methods are even examined.

Even though your Equals method is "better" in terms of converting the argument types to the formal parameter types, the compiler always prefers "normal" methods. You'll have to give your method a different name.

However, you can always use the Enumerable.SequenceEquals method. I don't believe that short-circuits the length check though (even though it could, for ICollection<T> implementations). You could always implement a more efficient version yourself though. Indeed, if you just change your existing array implementation to be called SequenceEquals or even ArrayEquals, that would be fine:

public static bool ArrayEquals(this byte[] array, byte[] bytes)
{
    // I'd personally use braces in all of this, but it's your call
    if (array.Length != bytes.Length) return false;
    for (int i = 0; i < array.Length; i++)     
        if (array[i] != bytes[i]) return false;

    return true;
}

Note that it would be quite nice to make it generic, but that would certainly cost a bit of performance as the comparison couldn't be inlined:

public static bool ArrayEquals<T>(this T[] first, T[] second)
{
    // Reference equality and nullity checks for safety and efficiency
    if (first == second)
    {
        return true;
    }
    if (first == null || second == null)
    {
        return false;
    }
    if (first.Length != second.Length)
    {
        return false;
    }        
    EqualityComparer<T> comparer = EqualityComparer<T>.Default;
    for (int i = 0; i < first.Length; i++)
    {
        if (!comparer.Equals(first[i], second[i]))
        {
             return false;
        }
    }
    return true;
}

I did this for the same purpose:

static class Global
{
    public static bool ArraysAreEqual(Array arr1, Array arr2)
    {
        if (arr1.Length != arr2.Length)
            return false;

        System.Collections.IEnumerator e1 = arr1.GetEnumerator();
        System.Collections.IEnumerator e2 = arr2.GetEnumerator();

        while(e1.MoveNext() && e2.MoveNext())
        {
            if(!e1.Current.Equals(e2.Current))
                return false;
        }
        return true;
    }
}

but notice that the .Equals() may even return false on reference-types when they are equal (I did not the test, but you can try with StringBuilder ). In my particular case I have only simple value-types

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top