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

时间:2012-01-11 12:23:09

标签: c# .net vb.net clr il

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

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

是否可以检查每种变量以查看值,还是实际参考本身?引用是否存储为某种编码值?我知道引用可以通过值传递,所以我假设是这样。

我认为这有助于新人了解他们,并且非常有趣地探索。

4 个答案:

答案 0 :(得分:10)

  

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

为了澄清,参考类型 变量的引用。引用是值。

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

  

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

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

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

答案 1 :(得分:5)

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

不要担心过多关于 这些内容在内存中的表示方式。除非你已经阅读了整个语言规范 - 无论如何谁都这样做? - 你真的不需要知道。真。不要忘记记住哪些数据存储在哪里 - 这可能是特定于实现的。

相反,请考虑语义,例如:传递给函数的值类型是复制,而引用类型是引用。这样的东西。

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

答案 2 :(得分:1)

您可以非常轻松地使用固定对象执行此操作;

GCHandle gch=GCHandle.Alloc(data, GCHandleType.Pinned);
IntPtr AddressInMemory=gch.AddrOfPinnedObject();

答案 3 :(得分:1)

您可以使用unsafe代码执行此操作:

    unsafe
    static void Main(string[] args)
    {
        string s = "Hello";

        fixed (char* pc = s)
        {                
            IntPtr p = (IntPtr)pc;
            Console.WriteLine(p);   // here is your meaningless address 
        }            
    }