为什么 .ToList().Distinct() 抛出错误,而 .Distinct().ToList() 不会在使用linq查询时抛出错误。
为什么 .ToList().Distinct() 抛出错误,而 .Distinct().ToList() 不会在使用linq查询时抛出错误。
我无法区分 LinqQuery.ToList().Distinct() 和 LinqQuery.Distinct().ToList();之间的区别,对我来说两者看起来相同。
考虑下面的示例代码:
ListstringList = new List (); List str1 = (from item in stringList select item).ToList().Distinct(); List str2 = (from item in stringList select item).Distinct().ToList();
str1显示错误信息:"无法将类型'System.Collections.Generic.IEnumerable'隐式转换为'System.Collections.Generic.List'。存在一个显式转换(是否遗漏了一个转换?)"
但是str2没有错误。
请帮助我理解这两者之间的区别。
谢谢
为什么使用LINQ查询时,.ToList().Distinct()
会报错,而.Distinct().ToList()
不会报错?
问题出现的原因是,.Distinct()
是一个在IEnumerable<T>
上操作的方法,并且返回一个IEnumerable<T>
(延迟评估)。IEnumerable<T>
是一个序列,它不是List<T>
。因此,如果你想要得到一个列表,把.ToList()
放在最后。
为了说明这个问题,我们来看一个简单的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表示新值 yield return value; } } }
为了让str1
能够正常工作,需要在最后添加.ToList()
。所以它应该是这样的:xxx.ToList().Distinct().ToList()。但这样做是不可取的,因为它创建了一个不必要的列表;现有的str2
的代码是更好的选择。
值得注意的是,如果处理的是对象而不是字符串,Marc的str2
和Marty的ToList().Distinct().ToList()
是不等价的。这取决于item的对象类型。在某些情况下,Distinct()
的项与Distinct()
的选择不是相同的对象。
解决方法就是将.ToList()
放在.Distinct()
之后,这样可以确保最终得到的是一个列表。