Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

why .ToList().Distinct() throws error but not the .Distinct().ToList() with linq query

Tags:

c#

linq

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

like image 512
Chandan Kumar Avatar asked Sep 18 '12 07:09

Chandan Kumar


1 Answers

.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;
        }
    }
}
like image 170
Marc Gravell Avatar answered Oct 21 '22 09:10

Marc Gravell