问题
I have the following class which is part of a statictical analysis package.
- The
MetricKey
object is used as a dictionary key. Decision
,MetricUnit
&Portfolio
are all enums.
I had to override the equality operator (==) to get dictionary key matching working. I used the guidance at http://msdn.microsoft.com/en-us/library/ms173147.aspx. The guidance said I should overload the GetHashCode method which I have done but I don't understand the implications of casting my enums to integers for the XOR (^) operation. Is what I've done valid or will I get conflicting hash codes due to my enum integer values overlapping?:
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;
}
}
回答1:
There is nothing wrong with the cast to int
- however, I would actually avoid xor - it is easy to create collisions with likely values of the enums (1,2,3, etc). Note that collisions don't break anything, but they can make things more expensive. I might use something like (picking at random taking inspiration from the C# compiler's handling of anonymous types):
int num = -1962473570;
num = (-1521134295 * num) + (int)Decision;
num = (-1521134295 * num) + (int)Unit;
return (-1521134295 * num) + (int)Portfolio;
来源:https://stackoverflow.com/questions/2320808/overloading-gethashcode-and-the-equality-operator-using-the-xor-operator-on-enum