Overloading GetHashCode and the Equality Operator Using the XOR Operator on Enumerations

I have the following class, which is part of an analytic analysis package.

  • The MetricKey object MetricKey used as a dictionary key.
  • Decision , MetricUnit and Portfolio are all listings.

I had to redefine the equality operator (==) in order to find work with the key for the dictionary. I used the manual http://msdn.microsoft.com/en-us/library/ms173147.aspx . The manual said that I should overload the GetHashCode method that I did, but I don’t understand what values ​​my enumerations enumerate for integers for the XOR (^) operation. Is this valid or am I getting conflicting hash codes due to overlapping integer enum values ​​?:

 public class MetricKey { public MetricKey(Decision decision, MetricUnit metricUnit, Portfolio portfolio) { Decision = decision; Unit = metricUnit; Portfolio = portfolio; } public Decision Decision { get; private set; } public MetricUnit Unit { get; private set; } public Portfolio Portfolio { get; private set; } public static bool operator == (MetricKey a, MetricKey b) { if (ReferenceEquals(a, b)) return true; if (((object) a == null) || ((object) b == null)) return false; return a.Decision == b.Decision && a.Unit == b.Unit && a.Portfolio == b.Portfolio; } public static bool operator != (MetricKey a, MetricKey b) { return !(a == b); } public override bool Equals(System.Object obj) { if (obj == null) return false; var metricKey = obj as MetricKey; if ((System.Object) metricKey == null) return false; return Decision == metricKey.Decision && Unit == metricKey.Unit && Portfolio == metricKey.Portfolio; } public bool Equals(MetricKey metricKey) { if ((object) metricKey == null) return false; return Decision == metricKey.Decision && Unit == metricKey.Unit && Portfolio == metricKey.Portfolio; } public override int GetHashCode() { return (int)Decision ^ (int)Unit ^ (int)Portfolio; } } 
+2
source share
1 answer

There is nothing wrong with casting to int - however, I would have avoided xor altogether - it is easy to create conflicts with likely enumeration values ​​(1,2,3, etc.). Note that collisions will not break anything, but they can make things more expensive. I could use something like ( random selection inspired by C # compiler handling for anonymous types):

 int num = -1962473570; num = (-1521134295 * num) + (int)Decision; num = (-1521134295 * num) + (int)Unit; return (-1521134295 * num) + (int)Portfolio; 
+3
source

All Articles