12

我有一个案例,我需要在不同的地方抓取一堆项目,但我的源是具有两个属性的对象集合,如下所示:

public class SkillRequirement
{
    public string Skill { get; set; }
    public string Requirement { get; set; }
}

我尝试按如下方式获取集合:

SkillRequirementComparer sCom = new SkillRequirementComparer();

var distinct_list = source.Distinct(sCom);

我试图为此实现一个IEqualityComparer<T>,但我对这个方法感到困惑GetHashCode()

比较器的类:

public class SkillRequirementComparer : IEqualityComparer<SkillRequirement>
{
    public bool Equals(SkillRequirement x, SkillRequirement y)
    {
        if (x.Skill.Equals(y.Skill) && x.Requirement.Equals(y.Requirement))
        {
            return true;
        }
        else
        {
            return false;
        }
    }

    public int GetHashCode(SkillRequirement obj)
    {
        //?????
    }
}

通常我只会GetHashCode()在一个属性上使用,但是因为我正在比较两个属性,所以我有点不知所措。我做错了什么,还是遗漏了一些非常明显的东西?

4

2 回答 2

13

您可以GetHashCode通过以下方式实现:

public int GetHashCode(SkillRequirement obj)
{
    unchecked
    {
        int hash = 17;
        hash = hash * 23 + obj.Skill.GetHashCode();
        hash = hash * 23 + obj.Requirement.GetHashCode();
        return hash;
    }
}

最初来自 J.Skeet

如果属性可以是null你应该避免 a NullReferenceException,例如:

int hash = 17;
hash = hash * 23 + (obj.Skill ?? "").GetHashCode();
hash = hash * 23 + (obj.Requirement ?? "").GetHashCode();
return hash;
于 2013-05-21T10:27:47.090 回答
1

尽管问题已经得到解答,但我也想链接以下堆栈溢出帖子。

GetHashCode -

为什么在重写 Equals 方法时重写 GetHashCode 很重要?

另外,在上面的回答中蒂姆施梅尔特说the properties can be null you should avoid a NullReferenceException

int hash = 17;
hash = hash * 23 + (obj.Skill ?? "").GetHashCode();
hash = hash * 23 + (obj.Requirement ?? "").GetHashCode();
return hash;

IEqualityComparer -

  1. 使用 IEqualityComparer 和 Equals/GethashCode Override 有什么区别
  2. GetHashCode 在 .NET 的 IEqualityComparer 中的作用是什么?
  3. 如何以及何时在 C# 中使用 IEqualityComparer

IEquatable - IEquatable 和仅覆盖 Object.Equals() 之间有什么区别?

Equals -重载 Equals() 的指南

class TwoDPoint : System.Object
{
    public readonly int x, y;

    public TwoDPoint(int x, int y)  //constructor
    {
        this.x = x;
        this.y = y;
    }

    public override bool Equals(System.Object obj)
    {
        // If parameter is null return false.
        if (obj == null)
        {
            return false;
        }

        // If parameter cannot be cast to Point return false.
        TwoDPoint p = obj as TwoDPoint;
        if ((System.Object)p == null)
        {
            return false;
        }

        // Return true if the fields match:
        return (x == p.x) && (y == p.y);
    }

    public bool Equals(TwoDPoint p)
    {
        // If parameter is null return false:
        if ((object)p == null)
        {
            return false;
        }

        // Return true if the fields match:
        return (x == p.x) && (y == p.y);
    }

    public override int GetHashCode()
    {
        //return x ^ y;
    }
}
于 2014-01-28T11:27:24.937 回答