Reputation: 27
Why can I use struct like class by ((I)o).Set(5, 5); It outputs 5,5 Yes, o is object but i can`t ((I)s).Set(4, 4); // output 1, 1 Why ((I)s).Set(4, 4) is output unchanged value but ((I)o).Set(5, 5) outputs changed?
I know that my code implicitly casting (citation) s to I (citation). Question is in code comments also.
interface I
{
void Set(int x, int y);
}
public struct S : I
{
int x, y;
public S(int x, int y)
{
this.x = x;
this.y = y;
}
public void Set(int x, int y)
{
this.x = x;
this.y = y;
}
public override string ToString()
{
return String.Format("{0} {1}", x, y);
}
}
class Program
{
static void Main(string[] args)
{
try
{
S s = new S(1, 1);
Console.WriteLine(s);
object o = s;
((I)o).Set(5, 5);
Console.WriteLine(o); // Why this works like class and outputs 5,5 instead of 1,1?
((I)s).Set(4, 4); // why i can`t change reference. why it outputs 1,1 instead of 4,4
}
catch { }
}
}
Upvotes: 0
Views: 55
Reputation: 3018
When you do casting (I)s
another instance of S
is created by copying s
and placed into heap as interfaces are reference types. So at this point you have two instances of S
: one in the stack and the other in the heap.
Consequently when you do ((I)s).Set(4, 4);
you are changing the second, the one in the heap.
Finally Console.WriteLine(s);
is printing out the first, the one in the stack.
To get correct output you must do:
var i = (I)s;
i.Set(4, 4);
Console.WriteLine(i);
Upvotes: 1
Reputation: 60
Because when
((I)s).Set(4, 4)
is called, what happens is
1) ((I)s) converts the struct into an object (boxing)
2) the Set method applies the changes to that object (and later it gets disposed of by garbage collector because no reference points to it), but the struct remains unchanged
Whether the ((I)o) casts one reference type into another, but the object stays the same.
Took explanation from here: https://blogs.msdn.microsoft.com/abhinaba/2005/10/05/c-structs-and-interface/
Upvotes: 1