How to make a reference type from int

I tried:

int i = 5; object o1 = i; // boxing the i into object (so it should be a reference type) object o2 = o1; // set object reference o2 to o1 (so o1 and o2 point to same place at the heap) o2 = 8; // put 8 to at the place at the heap where o2 points 

after running this code, the value in o1 is still 5, but I was expecting 8.

Did I miss something?

+6
source share
4 answers

This is not how variables work in C #. This has nothing to do with the types of boxing values.

Consider this:

 object o1 = new object(); object o2 = o1; o2 = new object(); 

Why do you expect o1 and o2 to contain a link to the same object? They are the same if you set o2 = o1 , but after setting o2 = new object() value changes (memory location, which the variable points to) o2 .

Perhaps what you are trying to do can be done as follows:

 class Obj { public int Val; } void Main() { Obj o1 = new Obj(); o1.Val = 5; Obj o2 = o1; o2.Val = 8; } 

At the end of Main Val o1 property will contain 8 .

+14
source

To do what you want to do, the value must be a property of the reference type:

 public class IntWrapper { public int Value { get; set; } public IntWrapper(int value) { Value = value; } } IntWrapper o1 = new IntWrapper(5); IntWrapper o2 = o1; o2.Value = 8; 
+4
source

@Ken gives you a great answer. This is the same behavior with struct (value types).

Note : mutable value types have very unintuitive behavior, do not try this at home :).

To get a similar behavior with type values, you need to implement some interface and set the property through the interface, because unboxing struct for your own type will always create a copy, and you cannot change the original value.

 void TortureMutableBoxedValueType() { object o1 = new IntWrapper(5); object o2 = o1; Console.WriteLine(((IValue)o1).Value); // outputs original 5 ((IValue)o2).Value = 8; Console.WriteLine(((IValue)o1).Value); // outputs new 8 } interface IValue { int Value {get;set;} } // Don't use mutable value types - this is just sample. public struct IntWrapper : IValue { int v; public int Value { get { return v;} set {v = value;}} public IntWrapper(int value) { v = value; } } 
+2
source

As Joel notes, although it is boxed, it is still a value type and, as such, it is not referenced, it is cloned. That's why you see this result - o1 and o2 point to different memory locations.

0
source

All Articles