OrderBy and List vs. IOrderedEnumerable
本文关键字:IOrderedEnumerable vs List and OrderBy | 更新日期: 2023-09-27 18:24:50
我在下面的代码中遇到了一个意外的问题。
List<string> items = new List<string>();
items = items.OrderBy(item => item);
此代码生成错误:
无法将类型"System.Linq.IOrderedEnumerable"隐式转换为"System.Collections.Generic.List"。存在显式转换(是否缺少强制转换?)
似乎我可以将items
更改为IEnumerable<string>
类型,错误就消失了。但我需要能够将项目添加到列表中,而IEnumerable
不支持这一点。
有人能帮我理解这个错误吗?最简单的解决方法是什么?简单地抛出结果安全吗?
为什么不使用Sort()
实例方法对列表进行适当排序;然后你可以稍后添加项目,如果你喜欢:
List<string> items = GetSomeItems();
items.Sort();
或者,像二进制搜索树一样使用有序集合。SortedSet<T>
可能符合您的需求。
其他人建议的解决方案:
items = items.OrderBy(item => item).ToList();
以新的顺序使用原始项目创建另一个列表。只有当您出于其他目的需要保留原始订单时,这才有用;这比将列表排序更浪费内存。
就理解错误而言,很简单:List<T>
不是IOrderedEnumerable<T>
的子类型,因此两者之间没有隐式引用转换。编译器建议的显式强制转换将满足编译器的要求,但在运行时会失败,因为OrderBy<T>
返回的对象不是从List<T>
继承的。
编辑
List<T>.Sort(Comparison<T>)
的一个例子,假设类型MyType
具有某种类型T的Key
属性,其中T : IComparable<T>
:
List<MyType> items = GetSomeItems();
items.Sort((a, b) => a.Key.CompareTo(b.Key));
您需要将IEnumerable
转换为List
。试试这个:
items = items.OrderBy(item => item).ToList();
您需要使用LINQ的ToList()方法
items = items.OrderBy(item => item).ToList();
不能直接从IEnumerable<>进行强制转换到列表<>
试试这个
items = items.OrderBy(item => item).ToList();
要对字符串列表进行排序,首先不需要Linq,只需使用Sort()
:
List<string> items = new List<string>();
//add items here
items.Sort();
OrderBy()是IEnumerable的扩展方法,而不是List。
当编译器遇到OrderBy()扩展方法时,它将范围变量强制转换为IOrderedEnumerable,在那里它可以使用IComparer等人通过CreateOrderedEnumerable方法执行所需的排序。排序后,编译器通常会将变量吐出为IEnumerable。
建议:使用var关键字在LinQ子句中键入"items"。
当然,上面使用Sort()和ToList()方法提供的选项会起作用——然而,使用它们会涉及贪婪的运算符,并且会失去延迟加载的优势。
这里有一个很好的细分:C#运行Sort()和OrderBy()之间的排序和OrderBy比较。