Why do these two comparisons have different results?

C#.NetEquality

C# Problem Overview


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

C# Solutions


Solution 1 - C#

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 - C#

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 - C#

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.

>reference

Solution 4 - C#

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.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMaxim ZhukovView Question on Stackoverflow
Solution 1 - C#Sergey BerezovskiyView Answer on Stackoverflow
Solution 2 - C#p.s.w.gView Answer on Stackoverflow
Solution 3 - C#Zaheer AhmedView Answer on Stackoverflow
Solution 4 - C#ServyView Answer on Stackoverflow