为什么.ToList()。Distinct()抛出错误但不抛出.Distinct()。带有linq查询的ToList()

时间:2012-09-18 07:04:00

标签: c# linq

我无法知道 LinqQuery.ToList()。Distinct() LinqQuery.Distinct()。ToList(); 之间的区别看起来一样。

考虑这个示例代码 :

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显示错误:“无法将类型'System.Collections.Generic.IEnumerable'隐式转换为'System.Collections.Generic.List'。存在显式转换(您是否错过了转换?)”

但str2没有错误。

请帮助我理解这两者之间的差异。 感谢

1 个答案:

答案 0 :(得分:18)

.Distinct()是一种对IEnumerable<T>进行操作的方法,返回 IEnumerable<T>(懒惰评估)。 IEnumerable<T>是一个序列:一个List<T>。因此,如果您想最终得到一个列表,请将.ToList()放在最后。

// 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>

为了说明原因,请考虑以下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;
        }
    }
}