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

Cha*_*mar 7 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();
Run Code Online (Sandbox Code Playgroud)

str1显示错误:"无法将类型'System.Collections.Generic.IEnumerable'隐式转换为'System.Collections.Generic.List'.存在显式转换(您是否错过了转换?)"

但str2没有错误.

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

Mar*_*ell 18

.Distinct()是操作上的一种方法IEnumerable<T>,并返回一个IEnumerable<T>(懒惰地评估).An IEnumerable<T>是一个序列:它不是 a 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>
Run Code Online (Sandbox Code Playgroud)

为了说明原因,请考虑以下粗略实现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;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • @Marty这是不可取的; 它在中间创建了一个不必要的列表; 现有的`str2`代码更可取. (2认同)