Question

I try to understand this code:

double b = 3;
object o = b;
Console.WriteLine(o.Equals(3));//false
Console.WriteLine(o.Equals(b));//true
Console.WriteLine( o == (object)b );//false
  1. Each new boxing makes different references of object b?
  2. If 1. is true, why o.Equals(b) is true?
  3. If Equals does not check references, why o.Equals(3) is false?

Thanks.

Was it helpful?

Solution

  1. Yes, each time you box a value type, a new object is created. More on boxing here.
  2. Equals check for value equality, not reference equality. Both o and b are the same: a double with a value of 3.0.
  3. 3 here is an int, not a double, and Equals for different types doesn't do any conversion to make them compatible, like the compiler is usually doing. o.Equals(3.0) will return true.

OTHER TIPS

double b = 3;

creates a new variable in stack with value 3

object o = b;

creates an object in the heap which reference the same place of b in the stack so you have the same variable with two references this is boxing

o.Equals(3)

is false because it creates a new anonymous variable with value 3 not b

o.Equals(b) 

is true because it's the same variable

o == (object)b

is false because == is comparing references in memory addresess but Equals compares the value of the variable itself

See this It explains all about equals behavior.

Every time an effort is made to convert a value type into a reference type, it must be boxed to a new object instance. There is no way the system could do anything else without breaking compatibility. Among other things, while one might expect that boxed value types would be immutable(*), none of them are. Every value type, when boxed, yields a mutable object. While C# and vb.net don't provide any convenient way to mutate such objects, trusted and verifiable code written in C++/CLI can do so easily. Even if the system knew of a heap object that holds an Int32 whose value is presently 23, the statement Object foo = 23; would have to generate a new Int32 heap object with a value of 23, since the system would have no way of knowing whether something might be planning to change the value of that existing object to 57.

(*)I would argue that they should be; rather than making all boxed objects mutable, it would be much better to provide a means by which struct types like List<T>.Enumerator could specify customizable boxing behavior. I'm not sure if there's any way to fix that now without totally breaking compatibility with existing code, though.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top