My goal is to create a method with the following requirements:
- Output should be consistent across different app domains (but which are running the same version of the .Net framework)
- Objects of different types should not generate the same hash
- Collisions are extremely unlikely
- The method will be called fairly frequently, so should not be too slow
The implementations that I’m considering look something like:
private static long GenerateHash<TKey>(TKey key)
{
long typeHash = typeof(TKey).GetHashCode();
long keyHash = key.GetHashCode();
return (typeHash << 32) + keyHash;
}
and
private static long GenerateHash<TKey>(TKey key)
{
using (var stream = new MemoryStream())
{
var formatter = new BinaryFormatter(); // Or other serialiser
formatter.Serialize(stream, key);
stream.Seek(0, SeekOrigin.Begin);
var hashAlgorithm = new SuitableHashAlgorithm(); // Not real class, need to find/write a hash algorithm that can compute 64 bit hashes...
var hash = hashAlgorithm.ComputeHash(stream);
return BitConverter.ToInt64(hash, 0);
}
}
Note, the possible nullness of key is not a consideration.
Any comments and potential pitfalls of these implementations welcomed along with any other possible ones.
Thanks
It appears that the requirements cannot be met with the stated method signature, thanks all for your comments, particularly @Marc Gravell.
I’ll introduce a suitable interface with a UniqueId property which all keys will implement.
I was hoping to avoid this in order to maintain backwards compatibility, but hey ho, you can’t always get what you want!