C# 动态类型和值类型是如何工作的?

C# 动态类型和值类型是如何工作的?,c#,.net,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()); //T

有一小段代码我无法理解:

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
但存储在堆上吗?还是我不明白的事?

TL;博士:
dts
ots
指向
ts
的相同、装箱的副本
ts
分别包含原始的
TestStruct


如您所知,其工作原理如下:

与类类型上的相同操作的一个关键区别是装箱和取消装箱将结构值复制到装箱实例中或从中复制出来。因此,在装箱或取消装箱操作之后,对取消装箱结构所做的更改不会反映在装箱结构中

因此,在这一行:

object ots = ts;
dynamic dts = ots;
您实际上是在复制您的
结构
,它将成为引用类型。现在有两个
TestStruct
的实例。在上,原始的
ts
,第二个是副本,也是一种引用类型(装箱的
TestStruct
)。因此,在这一行之后:

object ots = ts;
dynamic dts = ots;
ts
的盒装副本由两个参考文件指向:
ots
dts
dts
是动态的这一事实与此无关。这样做的目的只是将类型检查推迟到运行时,之后,它的行为就像
对象

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


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

为什么您认为它们引用的是同一个变量?你为什么认为它们存放在哪里很重要?你能解释一下你期望看到什么以及为什么会看到吗;(TestStruct)ots)。a将返回4,因此我认为它们引用了相同的变量。我希望在这行代码dts中看到取消装箱。a=4;谢谢,我知道装箱/拆箱的事。我被dts.GetType()弄糊涂了。它返回TestStruŠt type,我认为dts是ValueType变量。@Frinkie哦,好的。我将添加一个关于dynamic关键字的解释,以便更好地匹配您的问题。