为什么这两个比较有不同的结果?

为什么这个代码返回true:

new Byte() == new Byte() // returns true 

但是这个代码返回false:

 new Byte[0] == new Byte[0] // returns false 

因为new Byte()创build值types,它们通过值进行比较(默认情况下,它将返回值为0 byte )。 而new Byte[0]创build数组,这是一个引用types,并通过引用进行比较(这两个数组的实例将有不同的引用)。

有关详细信息,请参阅值types和引用types文章

字节是.NET中的值types ,这意味着当且仅当两个字节具有相同的值时, ==运算符才返回true。 这也被称为价值平等

但是,数组是.NET中的引用types ,这意味着==运算符返回true,当且仅当它们引用内存中相同的数组实例时。 这也被称为参考平等身份

请注意,对于引用types和值types, ==运算符都可以被重载。 例如, System.String是引用types,但string==运算符按顺序比较数组中的每个字符。 请参阅重载Equals()和Operator ==(C#编程指南)的指导原则 。

如果要testing数组是否包含完全相同的值(按顺序),则应考虑使用Enumerable.SequenceEqual而不是==

比较引用实际上是比较指针地址,不同的是返回false和value地址的原因不pipe比较值。

编译器尝试将值types存储在寄存器中,但是由于寄存器数量有限,在引用types处于堆栈中的值的情况下,堆栈中的值会进一步存储,而引用types为堆中存储器地址的值。

这里的比较比较第一种情况下堆栈中的值和第二种情况下堆中的值是不同的。

参考

==运算符有一个重载操作符,其中两个操作数都是bytetypes的,并被实现为比较每个字节的值; 在这种情况下,你有两个零字节,它们是相等的。

对于数组而言, ==运算符不会被重载,所以在第二种情况下,使用了具有两个object操作数的重载(因为数组是typesobject ),并且它的实现将引用与两个对象进行比较。 对两个数组的引用是不同的。

值得注意的是,这与byte是一个值types和数组是引用types的事实没有任何关系(直接)。 byte==运算符具有值语义,因为该实现具有特定的运算符重载。 如果这个重载不存在,那么就不会有两个字节是有效操作数的重载,因此这些代码根本就不会编译 。 您可以通过创build一个自定义struct并将其与==运算符的两个实例进行比较来轻松地看到这一点。 代码将不会编译,除非您提供您自己的==这些types的实现。