Reputation: 195
I've read about ref and value types in c# but don't know in the following example why y = 10
although x
and y
are reference types?
object x = 10;
object y = x;
x = 20;
Console.WriteLine(y); //why y = 10 although x and y are reference types?
And if you convince me of the reason, how could I change the object that is referenced by both x and y?
Upvotes: 0
Views: 111
Reputation: 195
I got your answers and this example may make the thing clearer.
class Complex
{
public int real;
public int imag;
}
static void Main(string[] args)
{
Complex c1 = new Complex();
Complex c2 = new Complex();
c2.real = 100;
c2.imag = 100;
object x = c1;
object y = x;
((Complex)x).imag = 50; //y here is changed
x = c2; //y here isn't changed because this line makes x is now pointing on sth else which doesn't matter with the object referenced by y
}
Upvotes: 0
Reputation: 1870
object x = 10;
object y = x;
After that x
and y
reference to same object:
x, y -> 10
But when you let x = 20
:
x -> 20
y -> 10
You can wrap value with class:
class Ref<T>
{
public T Value;
public static implicit operator T(Ref<T> x)
{
return x.Value;
}
public static implicit operator Ref<T>(T x)
{
return new Ref<T>() { Value = x };
}
}
And then:
Ref<int> x = 10;
Ref<int> y = x;
// x, y -> Ref -> 10
x.Value = 20;
// x, y -> Ref -> 20
Console.WriteLine(y); // y is 20 (or rather y.Value is 20)
Upvotes: 3
Reputation: 6430
The statement -
Object x = 10
has a special name and it is called Boxing. That is wrapping a value type inside a reference type. You might be thinking that this should create a reference. Yes you are right. But this also means a new object is created - as mentioned in the doc -
When a value type is boxed, a new object must be allocated and constructed.
https://msdn.microsoft.com/en-us/library/yz2be5wk.aspx
Now when you do -
object y = x;
Y and X are same object here pointing to same memory location. This far is okay. But the next statement -
x = 20;
is causing the exception. You see, this statement is another boxing and as boxing creates new instances, this is creating another new object with value 20 and putting/referring that with X.
So, Y is pointing to the last memory location where X is pointing to a new memory location.
You can understand why by visiting the link I mentioned above.
And if you convince me of the reason, how could I change the object that is referenced by both x and y? => You can't! Because C# does not support explicit pointers and you are using value types.
However if X and Y were reference types (i.e. Class
objects) then you could have done that.
Upvotes: 0
Reputation: 726987
Let's ignore the object
type for a moment. When you make an initialization like that
SomeType y = x;
y
becomes an alias to x
if SomeType
is a reference type class
, or it becomes a copy of x
if SomeType
is a value type struct
.
The situation when it becomes visible is when SomeType
is mutable. In situations with reference types changing the content of the object referenced through x
would also change y
, because it's the same object. If it is a copy, however, changing x
has no effect on the y
.
Since your code uses objects of boxed immutable type wrapping integer primitives, this assignment
x = 20;
makes variable x
refer to an entirely different immutable object. The value of y
remains unchanged.
Upvotes: 3