Gleb
Gleb

Reputation: 1432

Distinct with the list of my class

I have a class:

private class Part
{
    public string Id { get; set; }
    public string Class { get; set; }

    public override bool Equals(object obj)
    {
        Part part = obj as Part;

        return this.Id == part.Id;
    }
}

Also I have a List of this class, so I need to use distinct on this list. Thats what I do:

List<Part> parts = new List<Part>();
//adding items
parts = parts.Distinct().ToList();

But nothing happens. Can anybody tell me whats wrong?

Upvotes: 3

Views: 601

Answers (2)

Dmitrii Bychenko
Dmitrii Bychenko

Reputation: 186748

When overriding Equals you have to override GetHashCode as well:

private class Part
{
    public string Id { get; set; }
    public string Class { get; set; }

    // Whenever overiding Equals
    // You have to override this method too
    public override int GetHashCode() {
      return String.IsNullOrEmpty(Id) ? 0 : Id.GetHashCode();
    }

    public override bool Equals(object obj)
    {
        Part part = obj as Part;

        // if obj is not of Part you should return false
        if (Object.ReferenceEquals(null, part))
          return false; 

        return this.Id == part.Id;
    }
}

The very reason of the misbehaviour is that Distinct first tests GetHashCode and only then Equals.

Upvotes: 8

Harsh Baid
Harsh Baid

Reputation: 7249

To perform Distinct operation on your class you need to supply Comparer implementation of IEqualityComparer<T>

Example:

public class SelectedItemComparer : IEqualityComparer<Part>
{

    public new bool Equals(Part x, Part y)
    {
        return x.Id == y.Id;
    }

    public int GetHashCode(Part source)
    {
        string code = source.Id.ToString();

        return code.GetHashCode();

    }
}

Usage:

List<Part> parts = new List<Part>();
//adding items
parts = parts.Distinct(new SelectedItemComparer()).ToList();

Reference: Distinctly LINQ – Getting a Distinct List of Objects

Upvotes: 0

Related Questions