1

我正在做一些 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;
}
4

3 回答 3

8

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

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

但是,您始终可以使用该Enumerable.SequenceEquals方法。我不相信会短路长度检查(即使它可以,对于ICollection<T>实现)。不过,您总是可以自己实现更高效的版本。实际上,如果您只是将现有的数组实现更改为 callSequenceEquals或 even 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;
}
于 2009-06-28T07:32:19.770 回答
6
using System.Linq;

byte[] a = {1,2,3}; 
byte[] b = {1,2,3}; 
bool same = a.SequenceEqual(b);
于 2010-06-23T22:50:59.653 回答
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 )。在我的特殊情况下,我只有简单的值类型

于 2010-07-13T16:47:09.530 回答