Reputation: 41
There is a small piece of code that I can not understand:
class Program
{
static void Main(string[] args)
{
var ts = new TestStruct() { a = 2 };
object ots = ts;
dynamic dts = ots;
ts.a = 6;
dts.a = 4;
Console.WriteLine(dts.GetType()); //Type is TestStruct
Console.WriteLine("ts.a =" + ts.a); //6
Console.WriteLine("unboxed ts.a =" + ((TestStruct)ots).a); //4
Console.WriteLine("dts.a =" + dts.a); //4
Console.ReadKey();
}
}
public struct TestStruct
{
public int a;
}
dts
and ots
refer to the same variable on the heap, but GetType
returns for dts
TestStruct
. dts
is TestStruct
but stored on the heap? Or something I do not understand?
Upvotes: 2
Views: 90
Reputation: 35891
dts
and ots
point to the same, boxed, copy of ts
. ts
contains the original TestStruct
separately.
As you may know, Boxing and unboxing works like this:
A key difference from the same operations on class types is that boxing and unboxing copies the struct value either into or out of the boxed instance. Thus, following a boxing or unboxing operation, changes made to the unboxed struct are not reflected in the boxed struct.
So in this line:
object ots = ts;
You are effectively making a copy of your struct
, and it becomes a reference type. You have now two instances of TestStruct
. On, original ts
, and the second one, a copy, which is also a reference type (boxed TestStruct
). Hence, after this line:
dynamic dts = ots;
the boxed copy of ts
is pointed to by two references: ots
and dts
. The fact that dts
is dynamic
is irrelevant here. What dynamic
does, is only deferring type checking until run time, and after this, it behaves just like object
:
The compiler packages together information about the operation, and that information is later used to evaluate the operation at run time. As part of the process, variables of type dynamic are compiled into variables of type object. Therefore, type dynamic exists only at compile time, not at run time.
You can observe this happening when going step by step through the code in the debugger and inspecting the values of ts.GetHashCode()
, ots.GetHashCode()
and dts.GetHashCode()
. The actual copying may take place not immediately but after you modify the struct.
Upvotes: 2