Сравнить объекты? - PullRequest
       23

Сравнить объекты?

5 голосов
/ 05 января 2011

Я просто должен сделать простое сравнение, т.е.

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

, но результат ложный, и их хэш-код также отличается, я что-то здесь упускаю?

Заранее спасибо!

Ответы [ 4 ]

12 голосов
/ 05 января 2011

Я не верю, что во фреймворке есть что-то, что обеспечит равенство массивов так, как вы бы хотели.Однако не так сложно написать собственную реализацию IEqualityComparer<T> для массивов.Например (скомпилировано, но не проверено):

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;
    }
}

(Обратите внимание, что в настоящее время предполагается, что elementComparer будет справляться с нулевыми значениями как для GetHashCode, так и Equals. Интерфейс не гарантирует, чтоно компараторы равенства по умолчанию на самом деле делают . Вы можете изменить приведенный выше код, чтобы он был более надежным, конечно ... У меня просто сейчас нет времени.)

Использование:

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" });
4 голосов
/ 05 января 2011

keya и keyb - это два совершенно отдельных объекта, которые, как оказалось, содержат одни и те же байты.

Если вы хотите сравнить, чтобы увидеть, имеют ли две строки одинаковые символы, возможно, вам следует взглянуть натакие методы, как String.Equals?

1 голос
/ 05 января 2011

Массивы являются ссылочными типами, поэтому проверяйте на равенство, чтобы увидеть, совпадают ли указатели. Это не так.

Если вы хотите сравнить элементы, а не сами массивы, вы можете import System.Linq и использовать keya.SequenceEqual(keyb).

1 голос
/ 05 января 2011

Это общее расширение должно помочь:

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;
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...