Reference uniqueness and object's ID

  • Thread starter Fernando Cacciola
  • Start date
F

Fernando Cacciola

Hi,

I need to produce an ID number that uniquely identifies a given object
instance.

(If the object is a boxed value, well, it won't really matter, but for
_shared_ reference-types I really need a unique ID)

What's the most efficient way to do this?

I'm thinking of using a Hashtable using the objects themselves as keys and
increasing integers as IDs.

Many of the reference-types that participate have "Equivalence" semantics
for equality testing, meaning that they override .Equals() to return True
when 2 instances (same or not) have the same value; which implies that they
also override GetHashCode() so I have to use my own hash code provider; but
that's not a problem.

Any idea about an alternative approach?

A related question: is there any way to determine if an objet is shared
(more than 1 reference to it)?

TIA

Fernando Cacciola
 
J

Jon Skeet [C# MVP]

Fernando Cacciola said:
I need to produce an ID number that uniquely identifies a given object
instance.

(If the object is a boxed value, well, it won't really matter, but for
_shared_ reference-types I really need a unique ID)

What's the most efficient way to do this?

I'm thinking of using a Hashtable using the objects themselves as keys and
increasing integers as IDs.

Many of the reference-types that participate have "Equivalence" semantics
for equality testing, meaning that they override .Equals() to return True
when 2 instances (same or not) have the same value; which implies that they
also override GetHashCode() so I have to use my own hash code provider; but
that's not a problem.

Any idea about an alternative approach?

I don't think you need your own hash code provider - I think you need
your own IComparer which just does reference equality. I would have
thought that using the object's own hash code would be the right way to
go.
A related question: is there any way to determine if an objet is shared
(more than 1 reference to it)?

Not that I know of. Depending on what you're using it for,
WeakReference might be helpful though.
 
D

David Browne

Fernando Cacciola said:
Hi,

I need to produce an ID number that uniquely identifies a given object
instance.

(If the object is a boxed value, well, it won't really matter, but for
_shared_ reference-types I really need a unique ID)

What's the most efficient way to do this?

I'm thinking of using a Hashtable using the objects themselves as keys and
increasing integers as IDs.

Many of the reference-types that participate have "Equivalence" semantics
for equality testing, meaning that they override .Equals() to return True
when 2 instances (same or not) have the same value; which implies that
they also override GetHashCode() so I have to use my own hash code
provider; but that's not a problem.

Any idea about an alternative approach?

You can supply your own IComparer for use in the hash table and override the
default comparison.

class ReferenceComparer : System.Collections.IComparer
{
public int Compare(object a, object b)
{
return object.ReferenceEquals(a,b)?0:1;
}
}
static void main(string[] args)
{
Hashtable t = new Hashtable(null,new ReferenceComparer());
string s2 = "a";
s2 = s2 + "bc";
t.Add(s2,2);
Console.WriteLine(t.ContainsKey("abc"));
//false s2 is a different string than the interned literal "abc"

string s1 = "abc";
t.Add(s1,1);
Console.WriteLine(t.ContainsKey("abc"));
//true, but only because "abc" is interned

Console.WriteLine(t.ContainsKey("abc ".Trim()));
//false


string s3 = s2;
t.Add(s3,3);
//fails because s3 references the same object as s2


}
A related question: is there any way to determine if an objet is shared
(more than 1 reference to it)?

No, not really. This is only known by the garbage collector during a
garbage collection. So you could get a WeakReference to the object, release
your strong reference, run a complete garbage collection, and check if it's
still alive. But that's hardly practical.

David
 
N

Nicholas Paldino [.NET/C# MVP]

Fernando,

There is no way to determine if an object has more than one reference to
it.

As for doing a comparison, I think that overriding Equals is a bad thing
in general. It's the type of thing that should be implemented on an
interface, I think.

For what you want, I think that you should cast both objects to object,
and then use the == comparison operator, or use the static ReferenceEquals
method on the Object class.

Hope this helps.
 
F

Fernando Cacciola

Jon Skeet said:
I don't think you need your own hash code provider - I think you need
your own IComparer which just does reference equality. I would have
thought that using the object's own hash code would be the right way to
go.

:) This is exactly what I ended up doing after I tried out some code.
Not that I know of. Depending on what you're using it for,
WeakReference might be helpful though.
Oh, I'll check this out. Txs!

Fernando Cacciola
SciSoft
 
F

Fernando Cacciola

David Browne said:
You can supply your own IComparer for use in the hash table and override
the default comparison.

class ReferenceComparer : System.Collections.IComparer
{
public int Compare(object a, object b)
{
return object.ReferenceEquals(a,b)?0:1;
}
}

Yes, this is what I finally did a little after I posted.
(Except that I just used operator== since operators works by overloading,
and in this case the arguments are of type object so it always performs
reference equality.
static void main(string[] args)
{
Hashtable t = new Hashtable(null,new ReferenceComparer());
Ha, didn't think of suppling null as the HashCodeProvider...
Good point!
No, not really. This is only known by the garbage collector during a
garbage collection. So you could get a WeakReference to the object,
release your strong reference, run a complete garbage collection, and
check if it's still alive. But that's hardly practical.
Hmm, yes, I see...
I essentially just thought about skipping the unique ID althogether for
objects which are not shared (because if they are not shared, a unique ID is
not important for my application).
But given the above it would be a mis-optimization :)

Fernando Cacciola
SciSoft
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top