一尘不染

.NET唯一对象标识符

c#

有没有办法获取实例的唯一标识符?

GetHashCode()指向相同实例的两个引用是相同的。但是,两个不同的实例可以(很容易)获得相同的哈希码:

Hashtable hashCodesSeen = new Hashtable();
LinkedList<object> l = new LinkedList<object>();
int n = 0;
while (true)
{
    object o = new object();
    // Remember objects so that they don't get collected.
    // This does not make any difference though :(
    l.AddFirst(o);
    int hashCode = o.GetHashCode();
    n++;
    if (hashCodesSeen.ContainsKey(hashCode))
    {
        // Same hashCode seen twice for DIFFERENT objects (n is as low as 5322).
        Console.WriteLine("Hashcode seen twice: " + n + " (" + hashCode + ")");
        break;
    }
    hashCodesSeen.Add(hashCode, null);
}

我正在编写一个调试插件,我需要获取某种ID作为参考,该ID在程序运行期间是唯一的。

我已经设法获得了该实例的内部地址,该地址在垃圾收集器(GC)压缩堆之前是唯一的(=移动对象=更改地址)。

堆栈溢出问题
Object.GetHashCode()的默认实现 可能相关。

这些对象不受我的控制,因为我正在访问使用调试器API进行调试的程序中的对象。如果我要控制这些对象,那么添加自己的唯一标识符将是微不足道的。

我想要用于构建哈希表ID->对象的唯一ID,以便能够查找已经看到的对象。现在,我像这样解决它:

Build a hashtable: 'hashCode' -> (list of objects with hash code == 'hashCode')
Find if object seen(o) {
    candidates = hashtable[o.GetHashCode()] // Objects with the same hashCode.
    If no candidates, the object is new
    If some candidates, compare their addresses to o.Address
        If no address is equal (the hash code was just a coincidence) -> o is new
        If some address equal, o already seen
}

阅读 386

收藏
2020-05-19

共1个答案

一尘不染

引用
对象的唯一标识符。我不知道将其转换为字符串等任何方式的方法。在压缩过程中,引用的值将发生变化(如您所见),但是到目前为止,每个先前的值A都会更改为值B。就安全代码而言,它仍然是唯一的ID。

如果所涉及的对象在您的控制之下,则可以使用弱引用(以避免垃圾回收)从您选择的ID(GUID,整数等)的引用中创建映射。但是,这将增加一定数量的开销和复杂性。

2020-05-19