Подтвердить что ты не робот

Как удалить дубликаты из коллекции с помощью IEqualityComparer, LinQ Distinct

Я не могу удалить дубликаты из коллекции, я внедрил IEqualityComparer для класса Employee, но я не получаю вывод

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
}
4b9b3361

Ответ 1

Забудьте IEqualityComparer и просто используйте Linq напрямую:

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

Ответ 2

Вот хороший учебник

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

Ответ 3

Вам необходимо переопределить метод 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});

Анонимные объекты имеют правильную реализацию для методов GetHashCode и Equals.

Ответ 4

Неправильная реализация hashcode:

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

Ответ 5

Также похоже, что вы сравниваете по ссылке вместо контента, поэтому функция сравнения не работает.

измените его на использование .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

Ответ 6

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

Для этого метода верните хэш-код свойств, которые вы сравниваете для равенства, вместо самого объекта. Сравнение хэш-кода объектов всегда будет false, поэтому ваш список никогда не будет фильтроваться для дубликатов.