如何使用IEqualityComparer,LinQ Distinct从集合中删除重复项

时间:2013-06-07 11:59:10

标签: c# linq list

我无法从集合中删除重复项,我已经为类Employee实现了IEqualityComparer仍然没有得到输出

static void Main(string[] args)
    {
        List<Employe> Employeecollection = new List<Employe>();

        Employeecollection.Add(new Employe("abc","def"));
        Employeecollection.Add(new Employe("lmn","def"));
        Employeecollection.Add(new Employe("abc", "def"));

        IEnumerable<Employe> coll = Employeecollection.Distinct(new Employe());

        foreach (Employe item in coll)
        {
            Console.WriteLine(item.fName + "   " + item.lName );
        }

    }

下面是Employee类实现,这里我实现了IEqualityComparer

class Employe : IEqualityComparer<Employe>
{
    public string fName { get; set; }
    public string lName { get; set; }

    public Employe()
    {

    }

    public Employe(string firstName, string LastName)
    {
        this.fName = firstName;
        this.lName = LastName;
    }

    #region IEqualityComparer<pcf> Members

    public bool Equals(Employe x, Employe y)
    {
        if (x.fName == y.fName && x.lName == y.lName)
        {
            return true;
        }

        return false;
    }

    public int GetHashCode(Employe obj)
    {
        return obj.GetHashCode();
    }

    #endregion
}

6 个答案:

答案 0 :(得分:94)

忘记IEqualityComparer并直接使用Linq:

EmployeeCollection.GroupBy(x => new{x.fName, x.lName}).Select(g => g.First());

答案 1 :(得分:5)

这是一个很好的tutorial

    public int GetHashCode(Employe obj)
    {
        return obj.fname.GetHashCode() ^ obj.lname.GetHashCode();
    }

答案 2 :(得分:4)

您需要在Employee中覆盖GetHashCode方法。你还没有这样做。下面给出了良好散列方法的一个示例:(由ReSharper生成)

public override int GetHashCode()
{
    return ((this.fName != null ? this.fName.GetHashCode() : 0) * 397) ^ (this.lName != null ? this.lName.GetHashCode() : 0);
}

现在调用Distinct后,foreach循环打印:

abc   def
lmn   def

在你的情况下,你正在调用对象的类GetHashCode,它对内部字段一无所知。

一个简单的注释,MoreLINQ包含DistinctBy扩展方法,可让您执行以下操作:

IEnumerable<Employe> coll = 
 Employeecollection.DistinctBy(employee => new {employee.fName, employee.lName});

匿名对象可以正确实现GetHashCodeEquals方法。

答案 3 :(得分:2)

哈希码实现不正确:

public override int GetHashCode()
{
    return 13 * fName.GetHashCode() + 7 * lName.GetHashCode();
}

答案 4 :(得分:0)

它看起来像是通过引用而不是内容进行比较,因此比较功能不起作用。

更改它以使用.Equals()而不是==它应该工作。 以下示例:

#region IEqualityComparer<pcf> Members

public bool Equals(Employe x, Employe y)
{
    if (x.fName.Equals(y.fName) && x.lName.Equals(y.lName))
    {
        return true;
    }

    return false;
}

public int GetHashCode(Employe obj)
{
    return obj.GetHashCode();
}

#endregion

答案 5 :(得分:-1)

public int GetHashCode(Employe obj)
{
    return obj.GetHashCode();
}

对于此方法,返回要比较的属性的哈希码,而不是对象本身。比较对象的哈希码将始终为false,因此您的列表永远不会被重复过滤。