代码之家  ›  专栏  ›  技术社区  ›  grenade

在枚举上使用XOR运算符重载GetHashCode和相等运算符

  •  2
  • grenade  · 技术社区  · 15 年前

    我有下面的课程,它是静态分析包的一部分。

    • 这个 MetricKey 对象用作字典键。
    • Decision , MetricUnit 和; Portfolio 都是枚举。

    我必须重写相等运算符(==)才能使字典键匹配工作。我在 http://msdn.microsoft.com/en-us/library/ms173147.aspx . 指南说我应该重载gethashcode方法,我已经做过了,但是我不理解将枚举强制转换为xor(^)操作的整数的含义。由于枚举整数值重叠,我所做的是有效的还是会得到冲突的哈希代码?:

    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 回复  |  直到 15 年前
        1
  •  3
  •   Marc Gravell    15 年前

    演员没有什么问题 int -但是,实际上我会避免使用xor——很容易与可能的枚举值(1、2、3等)产生冲突。注意碰撞不会 打破 任何东西,但它们可以使东西更贵。我可能会用( 随机挑选 从C编译器对匿名类型的处理中获得灵感):

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