OrderBy和List与IOrderedEnumerable

时间:2012-02-14 22:53:11

标签: c# linq

我遇到了以下代码的意外问题。

List<string> items = new List<string>();
items = items.OrderBy(item => item);

此代码生成错误:

  

无法将类型'System.Linq.IOrderedEnumerable'隐式转换为'System.Collections.Generic.List'。存在显式转换(您是否错过了演员?)

看来我可以将items更改为IEnumerable<string>类型,但错误消失了。但我需要能够将项目添加到列表中,IEnumerable不支持。

有人可以帮助我理解这个错误,最容易解决的是什么?简单地投射结果是否安全?

6 个答案:

答案 0 :(得分:43)

为什么不使用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的某个类型为Key的{​​{1}}属性T : IComparable<T>

List<MyType> items = GetSomeItems();
items.Sort((a, b) => a.Key.CompareTo(b.Key));

答案 1 :(得分:17)

您需要将IEnumerable转换为List。试试这个:

items = items.OrderBy(item => item).ToList();

答案 2 :(得分:6)

试试这个

items = items.OrderBy(item => item).ToList();

答案 3 :(得分:5)

您需要使用LINQ的ToList()方法

items = items.OrderBy(item => item).ToList();

您无法直接从IEnumerable&lt;&gt;转换列出&lt;&gt;

答案 4 :(得分:4)

为了排序字符串列表,您首先不需要Linq - 只需使用Sort()

List<string> items = new List<string>();
//add items here
items.Sort();

答案 5 :(得分:1)

OrderBy()是IEnumerable的扩展方法 - 而不是List。

当编译器遇到OrderBy()扩展方法时,它会将范围变量强制转换为IOrderedEnumerable,它可以使用IComparer等人通过CreateOrderedEnumerable方法执行所需的排序。一旦排序,编译器就会将变量吐出为IEnumerable - 通常。

建议:使用var关键字输入&#39; items&#39;在LinQ条款中。

当然,使用Sort()和ToList()方法提供的上述选项也可以使用 - 但是,使用它们会涉及贪婪的运算符,并且您将失去延迟加载的优势。

这里有一个很好的细分: 运行Sort()和OrderBy()之间的C# Sort and OrderBy comparison