Remove duplicate items from Generic List

Most of times we use extensions like IList, IEnumerable, etc. which comes with .NET Framework 3.5. Other day when I was using these generic list with my custom class, I came across one of its shortcoming. Like it offers methods like Select(), Where() and GroupBy() which takes something called lambda as parameters. A few query operators, such as Distinct(), do not take lambdas as parameters. As a result, they are easy to call.

The parameter less Distinct() removes duplicates from a list, based on their hash. Now this is all works fine when you use predefined data types for generic list. Trouble starts when you use your own class with generic list. At that time Distinct() most probably will not work. So we need some thing which actually removes duplicate entries from list.

To solve this we can use IEqualityComparer which is also an parameter in Distinct() for one of the overloaded method. The Distinct() method with IEqualityComparer parameter returns an unordered sequence that contains no duplicate values. If comparer is null, the default equality comparer, Default, is used to compare values. Using this method one can avoid using lambda expressions. To understand the power of LINQ you do not need to understand lambdas.

Lets see an example that will make this very clear.

First we will create our class (we will create class for car)

public class Car
    public string ModelName { get; set; }
    public int Price { get; set; }
    public string Type { get; set; }

Then we have to create a class which will inherit IEqulityComparer and we have override two of their methods, namely Equals() and GetHashCode()

// Custom comparer for the Car class.
class CarComparer : IEqualityComparer<Car>
    // Cars are equal if their model names and car price are equal.
    public bool Equals(Car x, Car y)
        // Check whether the compared objects reference the same data.
        if (Object.ReferenceEquals(x, y)) return true;

        // Check whether any of the compared objects is null.
        if (Object.ReferenceEquals(x, null) || Object.ReferenceEquals(y, null))
            return false;

        // Check whether the cars' properties are equal.
        return x.ModelName == y.ModelName && x.Price == y.Price;

    // If Equals() returns true for a pair of objects,
    // GetHashCode must return the same value for these objects.

    public int GetHashCode(Car car)
        // Check whether the object is null.
        if (Object.ReferenceEquals(car, null)) return 0;

        // Get the hash code for the ModelName field if it is not null.
        int hashModelName = car.ModelName == null ? 0 : car.ModelName.GetHashCode();

        // Get the hash code for the price field.
        int hashCarPrice = car.Price.GetHashCode();

        // Calculate the hash code for the product.
        return hashModelName ^ hashCarPrice;

Once we have defined the comparer, we can use IEnumerable sequence of Car objects in Distinct() method, as shown in the following example

List<Car> cars= {
        new Car { ModelName = "Merd", Price = 15000, Type = "Basic" },
        new Car { ModelName = "Ferrari", Price = 25000, Type = "Pro" },
        new Car { ModelName = "Porsche", Price = 50000, Type = "Adv" },
        new Car { ModelName = "Merd", Price = 15000, Type = "Modern" },
        new Car { ModelName = "Range Rover", Price = 77000, Type = "Luxurious" } };

//Exclude duplicates.

IEnumerable<Car> noduplicates = cars.Distinct(new CarComparer());

foreach (var car in noduplicates)
    Console.WriteLine(car.ModelName + " " + car.Price);

    This code produces the following output:
    Merd 15000
    Ferrari 25000
    Porsche 50000
    Range Rover 77000

Here we can notice that even Type property being different for ModelName “Merd” it only showed the first one, because we have defined the comparer only for two of its properties. If we will include the third property as well in comparer then it will show one more “Merd” in output of different type.

My personal experience with this IEqualityComparer is that I had a parser which gave me records of around 2300+ for which I have used generic list with my custom class. To find duplicates was hell for me, because parameter less Distinct() didn’t actually solved my problem. That’s why I had to create custom comparer which solved my problem and amazing reduce the looping and no of duplicate records which reduced to around 300. Ohhhh….awesome! isn’t it?

Find more at

Tagged with: , , ,
  • Greatings, Interesting, I quote it on my site later.


  • I would like to exchange links with your site
    Is this possible?

  • Great information! I’ve been looking for something like this for a while now. Thanks!

  • interesting, thanks

  • Thanks for some quality points there. I am kind of new to online , so I printed this off to put in my file, any better way to go about keeping track of it then printing?

  • Ron Tedwater

    Really nice post,thank you

  • Nice site, nice and easy on the eyes and great content too.

  • Liza Willenborg

    I’m happy I found this post. It is exactly what I needed to know. Thanks

  • So helpful and so useful post. Thanks for such informative post. Good job.

  • Thank you, I have recently been searching for information about this topic for ages and yours is the best I have discovered so far.

  • Im glad to see this informative article. Thanks for such helpful and useful post.

  • I enjoyed to find this article. I like your point of view. Thanks a lot. Cheers

  • Get rid of the bird. It ruins your site.

  • Andy

    awesome! thanks for sharing this.