在C ++中,显示指向对象的指针的实际值非常简单。例如:
void* p = new CSomething();
cout << p;
有没有办法在.NET中做这样的事情?
这样做的价值只会是教育性的,例如为了示范的目的,如显示学生看到的价值,而不仅仅是比较参考相等或无(无)证明浅拷贝,不变性等。
答案 0 :(得分:7)
您可以使用GCHandle
获取固定对象的地址。 GC可以移动对象,因此获取的唯一合理地址是固定对象之一。
GCHandle handle = GCHandle.Alloc(obj, GCHandleType.Pinned);
Console.WriteLine(handle.AddrOfPinnedObject().ToInt32());
handle.Free();
请记住,GCHandle
只会固定原始或blittable类型的对象。某些对象是blittable(您可以将其设置为演示目的,因此它可以工作)但任何引用类型都不会是blittable。
您需要使用[StructLayout(LayoutKind.Sequential)]
添加显式的blittable描述,或使用调试器直接检查不符合这些条件的对象的地址。
答案 1 :(得分:6)
如果这是出于教育目的,我建议您使用调试器。如果您将SOS.dll(它是.NET框架的一部分)加载到WinDbg甚至Visual Studio中,您可以检查内存中的实际对象。
E.g。列出堆使用!dumpheap -stat
命令。 !do
命令将指定内存地址上的管理对象转储,依此类推。 SOS有许多命令可以让你检查内部的.NET结构,所以它是一个非常有用的工具,可以学习更多有关运行时的知识。
通过使用调试器,您不仅限于查看演示应用程序。您可以查看实际应用程序的详细信息。此外,您将获得一些非常有用的调试技巧。
使用WinDbg + SOS进行调试有几个很好的介绍。查看Tess' blog了解大量教程。
答案 2 :(得分:3)
RuntimeHelpers.GetHashCode将为您提供基于身份的哈希码。实际上,这可能是基于地址。如上所述:
“RuntimeHelpers.GetHashCode非常有用 在你关心的场景中 对象身份。两个字符串 相同的内容将返回 不同的价值观 RuntimeHelpers.GetHashCode,因为 它们是不同的字符串对象, 虽然他们的内容是一样的。“
字符串文字的实习是主要的可能例外。这在C ++中实际上是相同的。
答案 3 :(得分:0)
据我所知,如果您为编译器提供 / unsafe 选项,您将被允许编写“不安全”代码,并且可以使用它来访问指针。
我没有对此进行过测试,但发现它in this artice
编辑:
似乎要记住的主要事情是,您必须使用unsafe
关键字的不安全代码标记任何代码:
unsafe public static void Main()
答案 4 :(得分:0)
在.Net中你根本不使用指针。因此,您将创建参考对象,您始终可以看到该值。
比较参考对象时,会比较参考,而不是实际值! (除了比较字符串,'=='超载)。
也许你要展示的一个.Net例子会详细说明......
答案 5 :(得分:0)
您可以在.NET中检索对象的地址,例如使用不安全的代码,但您获取的地址只是临时的 - 它将是您获取地址的快照。 / p>
下次发生垃圾收集时,对象的地址可能会发生变化:
垃圾收集器的存在是@ Jesper中int*
指针存在于{ }
块范围内的原因。指针仅在该块内固定;一旦执行离开块,该对象有权被收集和/或移动。
答案 6 :(得分:-2)
unsafe
{
object o = new Object();
int *ptr = &o; //Get address
Console.WriteLine((int)ptr); //Write address
}
您需要使用/ unsafe开关
进行编译