views:

90

answers:

4

Im doing some queries to a active directory, building up my own Dictionary to contain name, phone and email per user.

then i store user to a file, something like this: domain\groupt\group\user;<checksum>

where path before ; is the unique id for the user (a user can be in different groups so i have to track that) and <checksum> is .GetHashCode() of that Dictinary object for that user.

Then i have a timer that every 30 sec checks AD and builds up the same dictinary for the user and looks up the id and checksum from the file.

BUT this is not working. For some reason .GetHashCode() generates a new int when there is no change to name, phone or email... so im thinking its not the function to use.

so how could i check if a object has changed in the way i tried to describe above?

A: 

try to override GetHashCode() to return something unique

mahmoud
+1  A: 

You may have to override the GetHashCode method of your user object to create your custom one.

Something like

public override int GetHashCode()
{
  return string.Concat(this.Domain,this.Name,...).GetHashCode();
}

But, anyway comparing the HashCodes only ensures you that the objects are not equal when the result is different, if the hashcodes are the same you still have to check if the contents is the same or not. HashCode is useful for distributing objects in Hastables, but not for real comparison.

You better implement IComparable interface in your classes.

jmservera
what if my object that i want to GetHashCode from is a Dictionary<string, string> currUser = new Dictionary<string, string>();? Same data is inserted but the hash changes in currUser.GetHashCode()
Jason94
That's why you have to create a User entity, so you can override the GetHashCode method. You can inherit from Dictionary<string,string> and create a new class UserDictionary:Dictionary<string,string> where you override the GetHashCode method. The GetHashCode method, as I commented before, is only for ensuring good distribution of objects into a HashTable, not for checking for equal, for this you have to implement IComparable.
jmservera
A: 

I suspect the reason your hashcodes are changing is that you have not overriden GetHashCode() in your class that combines your three fields, so it is using the default implemenation which will return a hashcode specific to the particular object (not its values). However, I would recommend not using GetHashCode at all for your problem as you need these values to persist to disk and be useful between invocations of your application.

GetHashCode() returns a hash that you can rely on only within the context of a single process instance (a single run). Implementations of GetHashCode are free to return values that are based upon memory ordering of elements which can change between process runs and, in addition, the values generated may differ between process architecture or between versions of .NET. See the documenation of GetHashCode for more details.

If you want something you can rely on when saved to disk and reloaded, you should switch to a hash function with behaviour that is well defined (or, alternatively, that you can control). A list of such algorithms can be found on the 'list of hash functions' Wikipedia page. In particular, the non-cryptographic ones are suitable for this task. (Although there is no reason, other than performance, why you couldn't use a cryptographic one.)

Paul Ruane
A: 

one point i haven't seen mentioned is that when you override the GetHashCode(), you should also override the Equals() to keep consistency and to avoid unexpected behaviour.

MadalinaA