动态和价值类型如何运作?

时间:2014-10-05 11:30:55

标签: c# .net

我无法理解一小段代码:

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;
}

dtsots引用堆上的相同变量,GetType返回dts TestStructdtsTestStruct但是存储在堆上?或者我不明白的事情?

1 个答案:

答案 0 :(得分:2)

TL; DR:

dtsots指向同一个盒装的ts副本。 ts分别包含原始TestStruct


如您所知,Boxing and unboxing的作用如下:

  

与类类型相同操作的主要区别在于装箱和拆箱将结构值复制到盒装实例中或从盒装实例中复制出来。因此,在装箱或拆箱操作之后,对未装箱的结构所做的更改不会反映在装箱的结构中。

所以在这一行:

object ots = ts;

您实际上正在制作struct的副本,它将成为参考类型。您现在有两个TestStruct个实例。在原始ts上,第二个是副本,它也是引用类型(装箱TestStruct)。因此,在这一行之后:

dynamic dts = ots;

ts的盒装副本由两个引用指向:otsdtsdtsdynamic这一事实与此无关。 dynamic所做的只是在运行时推迟类型检查,在此之后,它的行为就像object

  

编译器将有关操作的信息打包在一起,该信息稍后用于评估运行时的操作。作为过程的一部分,dynamic类型的变量被编译为object类型的变量。因此,类型dynamic仅在编译时存在,而不是在运行时存在。

您可以在逐步调试调试器中的代码并检查ts.GetHashCode()ots.GetHashCode()dts.GetHashCode()的值时观察到这种情况。实际复制可能不是立即进行,而是在修改结构后进行。