repeatedly calling HashCode.Combine


repeatedly calling HashCode.Combine



Is it correct to repeatedly call HashCode.Combine ?



I am trying to create a general extension method to produce an object hashcode from combining the hashcodes of all its properties like this:


using System;
public static int GetCombinedPropertiesHashCode(this object obj)
{
int hash = obj.GetType().GetHashCode();
foreach (var property in obj.GetType().GetProperties()) hash=HashCode.Combine(hash, property.GetHashCode());
return hash;
}



I am not sure if accumulating hashcodes like this will produce a unique hash ?
If not how can I do this correctly ?





What does HashCode.Combine() do?
– Sach
2 days ago


HashCode.Combine()





it's part of new .NET Core System namespace, can't find the docs ATM
– kofifus
2 days ago






Related: github.com/dotnet/coreclr/issues/15508
– stuartd
2 days ago





Seems fine. Depending on the number of items to combine, you could consider a divide&conquer approach to reduce the number of calls (from N to log(N)) at the expanse of some memory to store temporary results.
– Julien Couvreur
2 days ago





@JulienCouvreur: I'm not following you here. Suppose we have 128 items which we wish to hash. The straightforward approach is h1 = i1.GetHashCode(); h2 = Combine(h1, i2.GetHashCode()); ... h128 = Combine(h127, i128.GetHashCode()); which has 128 hashes and 127 combines. What divide-and-conquer algorithm do you propose that has 7 hashes and combines?
– Eric Lippert
2 days ago


h1 = i1.GetHashCode(); h2 = Combine(h1, i2.GetHashCode()); ... h128 = Combine(h127, i128.GetHashCode());




1 Answer
1



Is it correct to repeatedly call HashCode.Combine ?



Yes. That is precisely what it is for.



I am trying to create a general extension method to produce an object hashcode from combining the hashcodes of all its properties



That is a strange thing to do. Your hash code is per type, not per object, so it is strange that your method takes an object. Why does it not simply take a type? And why is it useful to form a hash of a type based on the hashes of its property info objects? That hash code has no particularly interesting characteristic that would make it useful to combine.



Can you explain what you are trying to do here? This code seems very wrong. Not because of your use of the combiner; because you're doing it at all and think that this produces something useful. A hash code is usually paired with an equality, but property infos are reference equal. This code makes no sense to me.



I am not sure if accumulating hashcodes like this will produce a unique hash ?



ABSOLUTELY IT WILL NOT PRODUCE A UNIQUE HASH. Hash codes are 32 bit integers; there are only four billion of them! There are more than four billion possible types, and so there are absolutely going to be at least two types that give the same hash code.



The purpose of hash codes is not to provide a unique value. If you need a unique value, make a GUID. If you need a unique hash, use a crypto-strength hash that has way, way more than 32 bits.



And thanks to the so-called "birthday paradox", you will get a collision very quickly. I've graphed the probability that your algorithm produces a non-unique result here: https://ericlippert.com/2010/03/22/socks-birthdays-and-hash-collisions/



Again, it sounds like you are doing something very wrong with your hash code if you believe that hash codes are unique.



Can you explain in much more detail what you are doing here? Your question is what we call an "XY" problem. You have some real problem, you have a crazy idea about how to solve it, and now you are asking a question about the crazy idea and it doesn't make any sense. Ask a question about the real problem; there's a better way to solve it.





thanks! I am trying to create classes who's instances are considered equal not only if their referenced are equal but also if all the fields are equal (I will have a custom Equals method for that), I need a custom grthashcode for them to reflect that if they are stored in collections and was trying to come up with something general
– kofifus
yesterday





That is first, a bad idea and second, not at all the code you wrote! You are not hashing property values at all. You're hashing objects that describe the properties.
– Eric Lippert
yesterday





ah I see .. but why is it a bad idea ?
– kofifus
yesterday






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Comments

Popular posts from this blog

paramiko-expect timeout is happening after executing the command

Opening a url is failing in Swift

Export result set on Dbeaver to CSV