我想在2字节数组之间使用Extension方法“Equals”

时间:2009-06-28 07:29:19

标签: c# comparison binary bytearray equality

我正在做一些byte []比较。

我试过==但这就像基本的Equals,其中:

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

我试图添加一个扩展方法,但由于重载的基类'Equals采用相同的参数,它转到基本方法而不是扩展,无论如何我可以使用Equals扩展(不要更改它的名称)。 ..)或(甚至更好)使用==运算符?

以下是我实际要比较的内容:

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

3 个答案:

答案 0 :(得分:7)

您当然不能使用扩展方法进行运算符重载。它不适用于Equals方法的原因是,如果任何方法在不使用扩展方法的情况下适用,则在扩展方法被检查之前将选择该方法。

即使你的Equals方法在将参数类型转换为形式参数类型方面“更好”,编译器总是更喜欢“普通”方法。你必须给你的方法一个不同的名字。

但是,您始终可以使用Enumerable.SequenceEquals方法。我不认为这会使长度检查短路(即使它可以用于ICollection<T>实现)。您可以自己实现更高效的版本。实际上,如果您只是将现有的数组实现更改为SequenceEquals甚至ArrayEquals,那就没关系了:

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

请注意,将它设为通用是非常好的,但由于无法内联比较,这肯定会花费一些性能:

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

答案 1 :(得分:6)

using System.Linq;

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

答案 2 :(得分:0)

我出于同样的目的这样做了:

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

但请注意,.Equals()甚至可能在引用类型相等时返回false(我没有测试,但你可以尝试使用StringBuilder)。在我的特殊情况下,我只有简单的价值类型