Why do these two comparisons have different results?
Why does this code return true:
new Byte() == new Byte() // returns true
but this code returns false:
new Byte[0] == new Byte[0] // returns false
Solution 1:
Because new Byte()
creates value type, which are compared by value (by default it will return byte
with value 0
). And new Byte[0]
creates array, which is a reference type and compared by reference (and these two instances of array will have different references).
See Value Types and Reference Types article for details.
Solution 2:
Bytes are value types in .NET, meaning that the ==
operator returns true if and only if the two bytes have the same value. This is also known as value equality.
But arrays are reference types in .NET, meaning the ==
operator returns true if and only if they refer to the same array instance in memory. This is also known as reference equality or identity.
Note that the ==
operator can be overloaded for both reference and value types. System.String
, for example, is a reference type, but the ==
operator for strings compares each character in the array in sequence. See Guidelines for Overloading Equals() and Operator == (C# Programming Guide).
If you want to test whether the arrays contain exactly the same values (in order) you should consider using Enumerable.SequenceEqual
instead of ==
.
Solution 3:
comparing reference is actually comparing pointer address, which are different that is the reason returning false and in value address not matter it compares value.
Compiler try to store Value type in registers but due to limited registers number further storage happens in Stack with values [Reference] while Reference type is in stack but value holding a address of memory address in Heap.
Comparison here compare the value present in stack which is in first case for both same while in second case it is addresses of heap which are different.
Solution 4:
There is an overload of the ==
operator in which both operands are of type byte
and it is implemented to compare the value of each byte; in this case you have two zero bytes, and they are equal.
The ==
operator isn't overloaded for arrays, so the overload having two object
operands is used (since arrays are of type object
) in the second case, and its implementation compares the references to the two objects. The reference to the two arrays are different.
It's worth noting that this has nothing (directly) to do with the fact that byte
is a value type and arrays are reference types. The ==
operator for byte
has value semantics only because there is a specific overload of the operator with that implementation. If that overload did not exist then there would be no overload for which two bytes would be valid operands, and as such the code wouldn't compile at all. You can see this easily enough by creating a custom struct
and comparing two instances of it with the ==
operator. The code will not compile, unless you provide your own implementation of ==
for those types.