8

i'm not able to know the difference between LinqQuery.ToList().Distinct() and LinqQuery.Distinct().ToList(); for me both looks same.

consider this sample code :

List<string> stringList = new List<string>();

List<string> str1  = (from item in stringList
                                select item).ToList().Distinct();

List<string> str2 = (from item in stringList
                                 select item).Distinct().ToList();

str1 shows an error as : "Cannot implicitly convert type 'System.Collections.Generic.IEnumerable' to 'System.Collections.Generic.List'. An explicit conversion exists (are you missing a cast?)"

but no error for str2 .

Please help me to understand the diffrence between these two. Thanks

Chandan Kumar
  • 2,617
  • 2
  • 19
  • 20

1 Answers1

19

.Distinct() is a method that operates on an IEnumerable<T>, and returns an IEnumerable<T> (lazily evaluated). An IEnumerable<T> is a sequence: it is not a List<T>. Hence, if you want to end up with a list, put the .ToList() at the end.

// note: this first example does not compile
List<string> str1  = (from item in stringList
                            select item) // result: IEnumerable<string>
                         .ToList() // result: List<string>
                         .Distinct(); // result: IEnumerable<string>

List<string> str2 = (from item in stringList
                             select item) // result: IEnumerable<string>
                         .Distinct() // result: IEnumerable<string>
                         .ToList(); // result: List<string>

For illustration of why this is so, consider the following crude implementation of Distinct():

public static IEnumerable<T> Distinct<T>(this IEnumerable<T> source) {
    var seen = new HashSet<T>();
    foreach(var value in source) {
        if(seen.Add(value)) { // true == new value we haven't seen before
            yield return value;
        }
    }
}
Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
  • In order the str1 to work, add "ToList() at the end. So it would look like tihs : xxx.ToList().Distinct().ToList() – Marty Sep 18 '12 at 07:08
  • 2
    @Marty that would be undesirable; it creates an unnecessary list in the middle; the existing `str2` code would be preferable. – Marc Gravell Sep 18 '12 at 07:09
  • Yes, I understand. Just put this in, for better understanding on how to make this work :) – Marty Sep 18 '12 at 07:42
  • FYI - If you are dealing with objects rather than strings, Marc's str2 is not equivalent to Marty's comment of ToList().Distinct().ToList(). It depends on what type of object item is. I have a scenario where Distinct() items are not the same thing as the Distinct() selection. – Paul May 01 '18 at 17:50