5
\$\begingroup\$

Linq methods like Distinct need IEqualityComparer object. But sometimes I just compares two objects and to create Comparer instance for that is seems redundant. So it would be nice to use static Equals method. But I'm not sure does not it break some guidelines.

public class ByteArrayComparer : EqualityComparer<byte[]>
{
    [DllImport("msvcrt.dll", CallingConvention = CallingConvention.Cdecl)]
    private static extern int memcmp(byte[] b1, byte[] b2, long count);

    //http://stackoverflow.com/a/1445405/2336304
    public override bool Equals(byte[] b1, byte[] b2)
    {
        return AreEqual(b1, b2);
    }

    // http://stackoverflow.com/questions/263400/what-is-the-best-algorithm-for-an-overridden-system-object-gethashcode/263416#263416
    // http://stackoverflow.com/a/7244729/2336304
    public override int GetHashCode(byte[] array)
    {
        unchecked
        {
            return array == null ? 0
                  : array.Aggregate(17, (current, element) => current * 31 + element.GetHashCode());
        }
    }

    public static bool AreEqual(byte[] b1, byte[] b2)
    {
        // Validate buffers are the same length.
        // This also ensures that the count does not exceed the length of either buffer. 
        return b1 != null && b2!= null && b1.Length == b2.Length && memcmp(b1, b2, b1.Length) == 0;
    }
}
\$\endgroup\$
3
\$\begingroup\$
  • The AreEqual() does not do what one would expect.

    As you have implemented the method, you say null != null.

  • GetHashCode()
    You should consider replacing the tenary with a simple if statement. IMHO you would gain in readability.

    public override int GetHashCode(byte[] array)
    {
        unchecked
        {
            if (array == null) { return 0; }
    
            return array.Aggregate(17, (current, element) => current * 31 + element.GetHashCode());
        }
    }  
    
  • using a static method here, won't do any harm IMHO.

\$\endgroup\$
  • \$\begingroup\$ I think if someone compares two objects then nonexistence of any means inequality. \$\endgroup\$ – SerG Dec 12 '14 at 16:47
  • \$\begingroup\$ So you say null != null . \$\endgroup\$ – Heslacher Dec 12 '14 at 16:56
  • 1
    \$\begingroup\$ How can two arrays be equal if there are no any arrays? :) \$\endgroup\$ – Vsevolod Goloviznin Dec 12 '14 at 19:11
1
\$\begingroup\$

It seems that you are not making use of EqualityComparer<T>.Default. The extension method IEnumerable.SequenceEqual also uses this comparer to determine whenever two sequences are equal.

So the answer is: If you can use the sequenceEquals do so, because there is already something within .Net framework that solves your problem.

Edit

So it turned out you were concerned about performance issues of SequenceEquals implementation.

You can always make a extension to IList<byte> that would have that algorithm instead, so the method could be called as it would be an instance method. But first be sure that this is a issue worth optimizing with a profiler!

\$\endgroup\$
  • \$\begingroup\$ But SequenceEqual is slow. \$\endgroup\$ – SerG Dec 12 '14 at 16:40
  • \$\begingroup\$ @SerG. As you didn't specify you were concerned about performance issues at any point of your question, I just couldn't guess. You can always make a extension to IList<byte> that would have that algorithm instead, so the method could be called as it would be an instance method. But first be sure that this is a issue worth optimizing with a profiler! \$\endgroup\$ – Bruno Costa Dec 12 '14 at 16:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.