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不支持这一点。

有人能帮我理解这个错误吗?最简单的解决方法是什么?简单地抛出结果安全吗?

OrderBy and List vs. IOrderedEnumerable

为什么不使用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比较。

相关文章:
  • 没有找到相关文章