猿问

C#中对象的内存地址

我前段时间编写了一个函数(针对.NET 3.5),现在我已升级到4.0


我无法正常工作。


该函数是:


public static class MemoryAddress

{

    public static string Get(object a)

    {

        GCHandle handle = GCHandle.Alloc(a, GCHandleType.Pinned);

        IntPtr pointer = GCHandle.ToIntPtr(handle);

        handle.Free();

        return "0x" + pointer.ToString("X");

    }

}

现在,当我调用它时-MemoryAddress.Get(new Car(“ blue”))


public class Car

{

    public string Color;

    public Car(string color)

    {

        Color = color;

    }

}

我得到错误:


对象包含非原始或不可复制的数据。


为什么它不起作用了?


现在如何获取被管理对象的内存地址?


波斯汪
浏览 1411回答 3
3回答

皈依舞

代替此代码,您应该调用GetHashCode(),它将为每个实例返回一个(希望的)唯一值。您也可以使用ObjectIDGeneratorclass,它保证是唯一的。

月关宝盒

如果您确实不需要内存地址,而是需要一些方法来唯一标识托管对象,则有更好的解决方案:using System.Runtime.CompilerServices;public static class Extensions{&nbsp; &nbsp; private static readonly ConditionalWeakTable<object, RefId> _ids = new ConditionalWeakTable<object, RefId>();&nbsp; &nbsp; public static Guid GetRefId<T>(this T obj) where T: class&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; if (obj == null)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return default(Guid);&nbsp; &nbsp; &nbsp; &nbsp; return _ids.GetOrCreateValue(obj).Id;&nbsp; &nbsp; }&nbsp; &nbsp; private class RefId&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; public Guid Id { get; } = Guid.NewGuid();&nbsp; &nbsp; }}这是线程安全的,并且在内部使用弱引用,因此不会有内存泄漏。您可以使用任何您喜欢的密钥生成方式。我在Guid.NewGuid()这里使用它是因为它简单且线程安全。更新资料我继续创建了一个Nuget包Overby.Extensions.Attachments,其中包含一些用于将对象附加到其他对象的扩展方法。有一个扩展名为GetReferenceId(),可以有效地执行此答案中的代码显示的内容。
随时随地看视频慕课网APP
我要回答