我想在 2 个字节数组之间有一个扩展方法“Equals”

问题描述 投票:0回答:3

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

我尝试过==,但这就像基本等于,其中:

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;
}
c# comparison binary arrays equality
3个回答
8
投票

您当然不能使用扩展方法进行运算符重载。它不适用于

Equals
方法的原因是,如果 any 方法在不使用扩展方法的情况下适用,则在检查扩展方法之前将选择该方法。

尽管您的

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

6
投票
using System.Linq;

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

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 )。在我的特殊情况下,我只有简单的值类型

© www.soinside.com 2019 - 2024. All rights reserved.