【问题标题】:Overloading GetHashCode and the equality operator using the XOR operator on enums在枚举上使用 XOR 运算符重载 GetHashCode 和相等运算符
【发布时间】:2011-01-20 05:15:29
【问题描述】:

我有以下类,它是静态分析包的一部分。

  • 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;
    }
}

【问题讨论】:

    标签: c# operators xor gethashcode


    【解决方案1】:

    转换为int 没有任何问题 - 但是,我实际上会避免异或 - 很容易与枚举的可能值(1、2、3 等)产生冲突。请注意,碰撞不会破坏任何东西,但它们会使事情变得更加昂贵。我可能会使用类似的东西(随机选择从 C# 编译器对匿名类型的处理中获得灵感):

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

    【讨论】:

    • (请注意,如果它比枚举更复杂,则应在其上调用 .GetHashCode() (首先检查是否为空)-碰巧,int 的 GetHashCode() 是“返回此",所以没什么意义 ;-p)
    猜你喜欢
    • 2011-02-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多