在具有C#</t>中两个属性的对象上实现IEqualityComparer <t>

时间:2013-05-21 10:24:12

标签: c# linq distinct iequalitycomparer

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

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()方法感到难过。

Comparer的类:

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(),但因为我在两个属性上进行比较,所以我有点不知所措。我做错了什么,或者遗漏了一些非常明显的东西?

2 个答案:

答案 0 :(得分:10)

您可以通过以下方式实施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的 originally

如果属性可以是null,则应避免使用NullReferenceException,例如:

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

答案 1 :(得分:1)

我想链接下面的堆栈溢出帖子,虽然问题已经回答了。

GetHashCode -

Why is it important to override GetHashCode when Equals method is overridden?

另外,在上面的回答中,Tim Schmelter说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. What is the difference between using IEqualityComparer and Equals/GethashCode Override
  2. What's the role of GetHashCode in the IEqualityComparer in .NET?
  3. How and when to use IEqualityComparer in C#
  4. IEquatable - What's the difference between IEquatable and just overriding Object.Equals()?

    等于 - Guidelines for Overloading 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;
        }
    }