.NET unique object identifier
.NET 4 and later only
Good news, everyone!
The perfect tool for this job is built in .NET 4 and it's called ConditionalWeakTable<TKey, TValue>
. This class:
- can be used to associate arbitrary data with managed object instances much like a dictionary (although it is not a dictionary)
- does not depend on memory addresses, so is immune to the GC compacting the heap
- does not keep objects alive just because they have been entered as keys into the table, so it can be used without making every object in your process live forever
- uses reference equality to determine object identity; moveover, class authors cannot modify this behavior so it can be used consistently on objects of any type
- can be populated on the fly, so does not require that you inject code inside object constructors
The reference is the unique identifier for the object. I don't know of any way of converting this into anything like a string etc. The value of the reference will change during compaction (as you've seen), but every previous value A will be changed to value B, so as far as safe code is concerned it's still a unique ID.
If the objects involved are under your control, you could create a mapping using weak references (to avoid preventing garbage collection) from a reference to an ID of your choosing (GUID, integer, whatever). That would add a certain amount of overhead and complexity, however.