GetHashCode() does not work as expected

G

Guest

I am trying to look for change in an instanciated object that contains a
generic list<>. I first get an int value of objA.GetHashCode(). I add a few
objects to the list<> collection in objA I compared the initial value with
the current hash code of objA and they were still the same. OK I thought
maybe if I compare the internal collections I would be more successful, so I
overrode the GetHashCode() method with the hashcode of the List. Still the
values are the same.

1) Am I missing how hashcode should be working?

2) What I'm trying to do is compare collections, so I'm trying to see if
there have been any changes to the collection to determine if I have to
perform an expensive operation. Is there a better way to do this?

TIA
-- Abe
 
J

Jesse McGrew

AbeR said:
I am trying to look for change in an instanciated object that contains a
generic list<>. I first get an int value of objA.GetHashCode(). I add a few
objects to the list<> collection in objA I compared the initial value with
the current hash code of objA and they were still the same. OK I thought
maybe if I compare the internal collections I would be more successful, so I
overrode the GetHashCode() method with the hashcode of the List. Still the
values are the same.

1) Am I missing how hashcode should be working?

Unfortunately, yes. Generally, with mutable reference types,
GetHashCode() isn't overridden to do anything interesting based on the
instance's fields. To understand why, consider this sample code:

// add an object reference to a hash table
MyReferenceObject inst = new MyReferenceObject();
inst.SomeField = 2001;

Hashtable tab = new Hashtable();
tab[inst] = 12345; // [1]

// now change the object
inst.SomeField = 1965;

// and try to retrieve the value
Console.WriteLine("Stored integer is {0}", tab[inst]); // [2]

Because Hashtable uses the key's hash code to know where to store and
find the value, if inst.GetHashCode() were to change between lines [1]
and [2], the Hashtable wouldn't be able to find the correct value -
even though the key you're using to search in line [2] is exactly the
same key you used to add in line [1], and it's still identical to the
key stored inside the Hashtable.

This isn't an issue with value types (or immutable reference types like
String), because you can't change the copy that's stored inside the
hash table.
2) What I'm trying to do is compare collections, so I'm trying to see if
there have been any changes to the collection to determine if I have to
perform an expensive operation. Is there a better way to do this?

I'd suggest writing a new collection class, a wrapper around List<>
that raises an event or updates a counter with each change.

Jesse
 
G

Guest

Thanks for the quick response. Back to the drawing board.

Happy New Year ;-)
-- Abe

Jesse McGrew said:
AbeR said:
I am trying to look for change in an instanciated object that contains a
generic list<>. I first get an int value of objA.GetHashCode(). I add a few
objects to the list<> collection in objA I compared the initial value with
the current hash code of objA and they were still the same. OK I thought
maybe if I compare the internal collections I would be more successful, so I
overrode the GetHashCode() method with the hashcode of the List. Still the
values are the same.

1) Am I missing how hashcode should be working?

Unfortunately, yes. Generally, with mutable reference types,
GetHashCode() isn't overridden to do anything interesting based on the
instance's fields. To understand why, consider this sample code:

// add an object reference to a hash table
MyReferenceObject inst = new MyReferenceObject();
inst.SomeField = 2001;

Hashtable tab = new Hashtable();
tab[inst] = 12345; // [1]

// now change the object
inst.SomeField = 1965;

// and try to retrieve the value
Console.WriteLine("Stored integer is {0}", tab[inst]); // [2]

Because Hashtable uses the key's hash code to know where to store and
find the value, if inst.GetHashCode() were to change between lines [1]
and [2], the Hashtable wouldn't be able to find the correct value -
even though the key you're using to search in line [2] is exactly the
same key you used to add in line [1], and it's still identical to the
key stored inside the Hashtable.

This isn't an issue with value types (or immutable reference types like
String), because you can't change the copy that's stored inside the
hash table.
2) What I'm trying to do is compare collections, so I'm trying to see if
there have been any changes to the collection to determine if I have to
perform an expensive operation. Is there a better way to do this?

I'd suggest writing a new collection class, a wrapper around List<>
that raises an event or updates a counter with each change.

Jesse
 
B

Ben Voigt

2) What I'm trying to do is compare collections, so I'm trying to see
Yes, a serial number generally will be the best way to do this. Might as
well implement lockless synchronization at the same time, because the serial
number plays an important role there as well.
 

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