比较对象?

时间:2011-01-04 21:00:45

标签: c# .net vb.net

我只需做一个简单的比较,即

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

但结果是假的,他们的哈希码也不同,我在这里遗漏了什么?

提前致谢!

4 个答案:

答案 0 :(得分:12)

我不相信框架中的任何内容会以您想要的方式提供数组相等性。但是,为数组编写自己的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将处理GetHashCodeEquals的空值。接口不保证,但默认的相等比较器实际上是处理它。你可以修改上面的代码,使其更加健壮,当然......我现在没有时间。)

用法:

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

答案 1 :(得分:4)

keyakeyb是两个完全独立的对象,恰好包含相同的字节。

如果你想比较看两个字符串是否有相同的字符,也许你应该看看像String.Equals这样的方法?

答案 2 :(得分:1)

这个通用扩展应该可以解决问题:

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

答案 3 :(得分:1)

数组是引用类型,因此测试相等性检查以查看指针是否相同。他们不是。

如果您想比较元素而不是数组本身,可以import System.Linq并使用keya.SequenceEqual(keyb)