我正在做一些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;
}
答案 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)。在我的特殊情况下,我只有简单的价值类型