Reference uniqueness and object's ID

  • Thread starter Thread starter Fernando Cacciola
  • Start date 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
 
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.
 
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
 
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.
 
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
 
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
 
Back
Top