我无法理解一小段代码:
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
和ots
引用堆上的相同变量,GetType
返回dts
TestStruct
。 dts
是TestStruct
但是存储在堆上?或者我不明白的事情?
答案 0 :(得分:2)
dts
和ots
指向同一个盒装的ts
副本。 ts
分别包含原始TestStruct
。
如您所知,Boxing and unboxing的作用如下:
与类类型相同操作的主要区别在于装箱和拆箱将结构值复制到盒装实例中或从盒装实例中复制出来。因此,在装箱或拆箱操作之后,对未装箱的结构所做的更改不会反映在装箱的结构中。
所以在这一行:
object ots = ts;
您实际上正在制作struct
的副本,它将成为参考类型。您现在有两个TestStruct
个实例。在原始ts
上,第二个是副本,它也是引用类型(装箱TestStruct
)。因此,在这一行之后:
dynamic dts = ots;
ts
的盒装副本由两个引用指向:ots
和dts
。 dts
为dynamic
这一事实与此无关。 dynamic
所做的只是在运行时推迟类型检查,在此之后,它的行为就像object
:
编译器将有关操作的信息打包在一起,该信息稍后用于评估运行时的操作。作为过程的一部分,dynamic类型的变量被编译为object类型的变量。因此,类型dynamic仅在编译时存在,而不是在运行时存在。
您可以在逐步调试调试器中的代码并检查ts.GetHashCode()
,ots.GetHashCode()
和dts.GetHashCode()
的值时观察到这种情况。实际复制可能不是立即进行,而是在修改结构后进行。