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());
Comments are closed.