We ran into a magic decimal number that broke our hashtable. I boiled it down to the following minimal case:
decimal d0 = 295.50000000000000000000000000m;
de
The documetation suggests that because of GetHashCode() being unpredictable, you should create your own. It's considered unpredictable because each Type has it's own implementation and since we don't know the internals of it we should create our own according to how we evaluate uniqueness.
However, I think the answer is that GetHashCode() is not using the mathematical decimal value to create the hash code.
Mathematically we see 295.50000000 and 295.5 as being the same. When you look at the decimal objects in the IDE this is true too. However, if you do a ToString() on both decimals you will see that the compiler sees them differently, i.e. you will still see 295.50000000. GetHashCode() is evidently not using the mathematical representation of the decimal for creating the hash code.
Your fix is simply creating a new decimal without all the trailing zeros which is why it works.