Imagine I have a single class, with two instances:
MyClass a = new MyClass(); MyClass b = new MyClass();
MyClass has a method PrintUniqueInstanceID:
void PrintUniqueInstanceID() { Console.Write("Unique ID for the *instance* of this class: {0}", [what goes here???] ); }
Ideally, the output would be something like:
Unique ID for the *instance* of this class: 23439434 // from a.PrintUniqueInstanceID Unique ID for the *instance* of this class: 89654 // from b.PrintUniqueInstanceID
So - what would I insert in "[what goes here???]
", above, which prints a unique number for every unique instance of the class?
Ideas
(optional) Background Information For Experts
The reason I need this is that I am using AOP and PostSharp to automatically detect threading issues. I need to look up each unique instance of the class in a dictionary, in order to verify that multiple threads are not accessing the same unique instance of a class (its ok if there is one thread per class instance).
Update
As others have pointed out, I should mention that I can't touch any of the existing classes in the 30,000 line project. PrintUniqueInstanceID, above, is an aspect (see PostSharp) that is added to the top level class, is inherited by every class in the entire project, and executes on every method entry in the entire project.
Once I have verified that everything is thread safe, I'll remove the aspect to restore performance.
Add a Guid property to your class, then in the constructor of the class assign it to NewGuid().
public class MyClass { public Guid InstanceID {get; private set;} // Other properties, etc. public MyClass() { this.InstanceID = Guid.NewGuid(); } void PrintUniqueInstanceID() { Console.Write("Unique ID for the *instance* of this class: {0}", this.InstanceID); } }
Based on the additional information we now have, I believe that you can solve your problem very easily using ConditionalWeakTable
(which is only from .NET 4 onwards).
You can therefore create such a global table inside your "manager" class and associate each object with a long
, a Guid
or anything else you might want¹. Whenever your manager encounters an object it can get its associated id (if you have seen it before) or add it to the table and associate it with a new id created on the spot.
¹ Actually the values in the table must be of a reference type, so you cannot use e.g. long
as the value type directly. However, a simple workaround is to use object
instead and let the long
values be boxed.
Isn't this a basic usage example for static
members?
class Foo { private static int instanceCounter; private readonly int instanceId; Foo() { this.instanceId = ++instanceCounter; } public int UniqueId { get { return this.instanceId; } } }
Of course you have to pay attention to the range of identifiers so that you don't start reusing them if billions of instances are created, but that's easy to solve.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With