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

发布于 2024-08-22 14:56:28 字数 1986 浏览 10 评论 0原文

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

  • MetricKey 对象用作字典键。
  • 决策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;
    }
}

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

人间☆小暴躁 2024-08-29 14:56:28

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

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

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;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文