Ali
Ali

Reputation: 1678

Compare Objects?

I just have to do a simple comparison i.e.

byte[] keya = System.Text.Encoding.ASCII.GetBytes("myFamilyColumn:1");
byte[] keyb = System.Text.Encoding.ASCII.GetBytes("myFamilyColumn:1");
Console.WriteLine(keya == keyb);

but the result is false, and their hash code is also different, am i missing something here?

Thanks in advance !

Upvotes: 6

Views: 2550

Answers (4)

Trystan Spangler
Trystan Spangler

Reputation: 1769

Arrays are reference types so testing for equality checks to see if the pointers are the same. They're not.

If you want to compare the elements and not the arrays themselves, you can import System.Linq and use keya.SequenceEqual(keyb).

Upvotes: 1

Jon Skeet
Jon Skeet

Reputation: 1499790

I don't believe there's anything in the framework which will give array equality in the way you'd want. However, it's not too hard to write your own implementation of IEqualityComparer<T> for arrays. For example (compiled but untested):

public static class ArrayEqualityComparer
{
    public static IEqualityComparer<T[]> Create<T>(
        IEqualityComparer<T> comparer)
    {
        return new ArrayEqualityComparer<T>(comparer);
    }
}

public sealed class ArrayEqualityComparer<T> : IEqualityComparer<T[]>
{
    private static readonly IEqualityComparer<T[]> defaultInstance = new
        ArrayEqualityComparer<T>();

    public static IEqualityComparer<T[]> Default
    {
        get { return defaultInstance; }
    }

    private readonly IEqualityComparer<T> elementComparer;

    public ArrayEqualityComparer() : this(EqualityComparer<T>.Default)
    {
    }

    public ArrayEqualityComparer(IEqualityComparer<T> elementComparer)
    {
        this.elementComparer = elementComparer;        
    }

    public bool Equals(T[] x, T[] y)
    {
        if (x == y)
        {
            return true;
        }
        if (x == null || y == null)
        {
            return false;
        }
        if (x.Length != y.Length)
        {
            return false;
        }
        for (int i = 0; i < x.Length; i++)
        {
            if (!elementComparer.Equals(x[i], y[i]))
            {
                return false;
            }
        }
        return true;
    }

    public int GetHashCode(T[] array)
    {
        if (array == null)
        {
            return 0;
        }
        int hash = 23;
        foreach (T item in array)
        {
            hash = hash * 31 + elementComparer.GetHashCode(item);
        }
        return hash;
    }
}

(Note that this currently assumes that elementComparer will cope with null values for both GetHashCode and Equals. The interface doesn't guarantee that, but the default equality comparers actually do handle it. You could modify the above code to be more robust, of course... I just don't have time right now.)

Usage:

IEqualityComparer<byte[]> x = ArrayEqualityComparer<byte>.Default;
bool equal = x.Equals(bytes1, bytes2);

IEqualityComparer<string[]> y = 
    ArrayEqualityComparer.Create(StringComparer.OrdinalIgnoreCase);
bool whatever = x.Equals(new[][] { "X", "Y" }, new[] { "x", "y" });

Upvotes: 12

ChaosPandion
ChaosPandion

Reputation: 78252

This generic extension should do the trick:

public static class ArrayExtensions
{
    public static bool ElementsEqual<T>(this T[] left, T[] right)
        where T : IEquatable<T>
    {
        if (left == null || right == null)
        {
            return !(left == null ^ right == null);
        }
        else if (left.Length != right.Length)
        {
            return false;
        }

        for (int i = 0; i < left.Length; i++)
        {
            if (!left[i].Equals(right[i]))
            {
                return false;
            }
        }

        return true;
    }
}

Upvotes: 1

Anon.
Anon.

Reputation: 60006

keya and keyb are two entirely separate objects that just happen to contain the same bytes.

If you want to compare to see if two strings have the same characters, perhaps you should look at methods like String.Equals?

Upvotes: 4

Related Questions