为什么这个字节[]不等于具有相同值的另一个字节[]

本文关键字:字节 另一个 不等于 为什么 | 更新日期: 2023-09-27 18:11:00

public static readonly byte[] TestArray=
    new byte[] { 0x75, 0xa5, 0x15, 0x19, 0xa0, 0x2e, 0xd9, 0x37, 0xb0, 0x4d };
public bool TestFunction() 
{
    MemoryStream s=new MemoryStream(
        new byte[] { 0x75, 0xa5, 0x15, 0x19, 0xa0, 0x2e, 0xd9, 0x37, 0xb0, 0x4d }
        );
    byte[] test=s.ToArray();
    return (test==TestArray);
}

我正在使用上面的简单代码。数组中的字节值是相等的。但是我的TestFunction()总是返回false。发生了什么事?

为什么这个字节[]不等于具有相同值的另一个字节[]

因为数组在。net中是引用类型,对于数组,==操作符只是检查它们是否是对内存中相同对象的引用。你需要SequenceEqual使用这个来比较每个字节:

test.SequenceEqual(TestArray);

因为您没有比较每个数组的单个成员;您正在比较引用到每个不相等的数组。

在这种情况下,==操作符检查引用是否相等,而不是检查字节数组的内容是否相等。你应该迭代字节数组,检查它们是否一个字节一个字节地相等,或者使用一个方法来检查。

我想你把它从你的代码中拿出来了,但是MemoryStream的使用有点毫无意义,你可以这样做:

byte[] test = new byte[] { 0x75, 0xa5, 0x15, 0x19, 0xa0, 0x2e, 0xd9, 0x37, 0xb0, 0x4d };

您正在比较引用到对象,即==操作符-在字节数组的情况下-当且仅当两个引用指向相同对象时返回true。但实际上你有两个不同的对象,它们有相同的内容。

您必须使用SequenceEqual方法来比较两个数组的内容

请注意,==操作符可以对某些类重载,以便比较对象的内容(甚至具有一些其他逻辑)。但是,对于字节数组,==没有重载,因此默认情况下只比较引用。

等号比较器不会进行所谓的"深度等号"检查。换句话说,等号操作符只检查两个数组/对象是否存储在内存中的相同位置(换句话说,是否对象引用相同)。

要检查两个数组的值是否相等,需要编写一个函数分别检查每个值。

因为byte[]是一个引用类型当你比较两个字节数组时你实际上是在比较它们的引用在内存中的位置而不是它们的值

MemoryStream.ToArray的代码为:

public virtual byte[] ToArray() {
    byte[] dst=new byte[this._length-this._origin];
    Buffer.InternalBlockCopy(this._buffer, this._origin, dst, 0, this._length-this._origin);
    return dst;
}

你得到false的真正原因是,你声明了两个数组,但是比较了另一个东西。这种比较即使在c语言中也不成立。

当,在您的示例中,您使用相等运算符(==)时,您正在比较每个人所说的数组引用,而不是它的值。

简单的测试:

byte[] originalArray = new byte[] { 0x75, 0xa5, 0x15, 0x19, 0xa0, 0x2e, 0xd9, 0x37, 0xb0, 0x4d };
byte[] sameReferenceArray = originalArray;
originalArray == sameReferenceArray; //true
byte[] sameContentArray = new byte[] { 0x75, 0xa5, 0x15, 0x19, 0xa0, 0x2e, 0xd9, 0x37, 0xb0, 0x4d };
originalArray == sameContentArray; //false