参考类型 - 我们可以看到实际参考吗?

m.e*_*son 7 .net c# vb.net clr il

由于不了解值类型的变量实际上是什么,因此引用类型和值类型之间的差异通常会让初学者感到困惑.我们知道:

  • 值类型存储实际
  • 引用类型仅存储对象的引用

是否有可能检查每种变量以查看值或实际参考本身?引用是否存储为某种编码值?我知道引用可以通过值传递,所以我假设如此.

我认为这有助于新人了解他们,并且非常有趣.

Eri*_*ert 10

是否有可能检查每种变量以查看值或实际参考本身?

只是为了澄清,则 a的引用类型的变量 一个参考.参考是值.

引用是一种值,就像int是一种值.与int不同,引用是一个只能复制解除引用的值 ; 您无法直接在C#中观察其值,因为它的值是垃圾收集器的实现细节.

引用是否存储为某种编码值?

对,就是这样.实际上,引用是32位或64位整数(取决于您是在32位还是64位进程中),它是指向垃圾收集器已知的某些结构的指针,该结构与引用对象的数据相关联.

如果要直接查看引用,则执行此操作的工具是调试器.将C#代码加载到调试器中,编译它,运行它,命中断点,然后查看堆栈状态和寄存器.稍微聪明一点,您应该能够找出哪些堆栈位置和寄存器对应于哪些局部变量.与值类型的局部变量对应的位置将包含值; 那些引用类型将包含看起来像指针的值.如果检查内存窗口中的那些指针,那么您将查看由垃圾收集器维护的描述对象内容的结构.

  • 我认为重要的是要注意,虽然现有的.net实现可以在引用变量中存储(对象 - 信息记录)的地址,但是不能保证将来的版本会这样做.例如,有可能参考变量的某些位是选择多个堆中的一个的索引,而其他位是该堆内的索引.虽然这样的系统对于现有处理器可能效率低,但围绕这种模型设计未来的处理器可能允许更有效的高速缓存利用率.现有的.net代码不应该关心这些细节. (3认同)

Dar*_*mas 5

这可能是Jon Skeet的一个,但我可能有不同的角度:

不要过分担心这些东西如何在记忆中表现出来.除非你已经阅读了整个语言规范 - 无论如何谁都这样做? - 你真的不需要知道.真.不要忘记记住哪些数据存储在哪里 - 这可能是特定于实现的.

相反,认为语义,例如,传递给函数的值类型的条款复制,而引用类型的引用.类似的东西.

你真的不想知道类型的声明实际上是什么.相信我.你想知道的是它的行为方式.

  • +1这里是Eric Lippert [说](http://blogs.msdn.com/b/ericlippert/archive/2009/02/17/references-are-not-addresses.aspx)同样的事情.地址是实现细节,语言规范在指定引用时没有提到地址.了解他们的行为方式,而不是他们的工作方式. (2认同)
  • 虽然我同意你的陈述,但我觉得这不是问题的重点.我想他想知道怎么做 - 而不是你对为什么不重要的看法.了解复杂功能的工作原理可以使您成为更好的工程师,即使您没有立即使用该知识. (2认同)
  • @ AdamG.Carstensen - 我同意你们两个人的观点:我没有真正回答你的问题.但你提到"帮助新人理解"是一个原因,我认为这对新人来说并没有多大帮助.但从VM实现的角度来看,这将是有趣的. (2认同)