Distinct LINQ

I have written about LINQ in the past and I truly believe it is the gateway to a better way of programming, surprisingly I have never used the Distinct method before this week. So I was rather surprised that for all my efforts simply using the Distinct method would not work even for an object as simple as the following:

public class WordViewModel
{
    public string Word
    {
        get {}
        set {}
    }
}


Basically this is a function of the fact that even for a type as simple this, LINQ really does not know how to use the property ‘Word’ to determine if a type is unique or not. So in order to use the Distinct method effectively we have to tell LINQ how to compare our types use the IEqualityComparer as follows

// Custom comparer for the Product class
class WordComparer : IEqualityComparer<WordViewModel>
{
    // Words are equal if their names are equal.
    public bool Equals(WordViewModel x, WordViewModel y)
    {
        if (Object.ReferenceEquals(x, y)) return true;

        if (Object.ReferenceEquals(x, null) || Object.ReferenceEquals(y, null))
            return false;

        //Check whether the properties are equal.
        return x.Word == y.Word;
    }

    // GetHashCode() should return the same value.
    public int GetHashCode(WordViewModel word)
    {
        if (Object.ReferenceEquals(word, null)) return 0;

        int hashProductName = word.Word == null ? 0 : word.Word.GetHashCode();
        int hashProductCode = word.Word.GetHashCode();

        //Get the hash code for Word
        return hashProductName ^ hashProductCode;
    }
}

So then my simple Distinct method gets passed my customized comparer and works like a charm!

var newlist = new List<WordViewModel>(
    list.Where(s => !s.Word.StartsWith("Start"))
    .Where(s => s.Word.Length > 5)
    .OrderBy(c => c.Word.Length).ThenBy(s => s.Word))
    .Distinct(new WordComparer());


Comment Section

Comments are closed.