C# OrderBy 和 List 与 IOrderedEnumerable

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9285426/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-09 06:43:10  来源:igfitidea点击:

OrderBy and List vs. IOrderedEnumerable

c#linq

提问by Jonathan Wood

I ran across an unexpected problem with the following code.

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

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

This code generates the error:

此代码生成错误:

Cannot implicitly convert type 'System.Linq.IOrderedEnumerable' to 'System.Collections.Generic.List'. An explicit conversion exists (are you missing a cast?)

无法将类型“System.Linq.IOrderedEnumerable”隐式转换为“System.Collections.Generic.List”。存在显式转换(您是否缺少演员表?)

It appears I can change itemsto be of type IEnumerable<string>and the error goes away. But I need to be able to add items to the list, which IEnumerabledoesn't support.

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

Can someone help me understand this error, and what the easiest fix is? Is it safe to simply cast the result?

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

采纳答案by phoog

Why not just sort the list in place using the Sort()instance method; then you can add items to it later if you like:

为什么不直接使用Sort()实例方法对列表进行排序;然后,如果您愿意,可以稍后向其中添加项目:

List<string> items = GetSomeItems();
items.Sort();

Or, use an ordered collection like a binary search tree. SortedSet<T>might fit the bill, depending on your needs.

或者,使用像二叉搜索树这样的有序集合。 SortedSet<T>可能符合要求,具体取决于您的需要。

The solution suggested by the others:

其他人建议的解决方案:

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

... creates another list with the original items in a new order. This is only useful if you need to preserve the original ordering for some other purpose; it's rather more wasteful of memory than sorting the list in place.

...以新顺序创建另一个包含原始项目的列表。这仅在您出于其他目的需要保留原始顺序时才有用;与对列表进行排序相比,它更浪费内存。

As far as understanding the error, it's simple: List<T>isn't a subtype of IOrderedEnumerable<T>, so there's no implicit reference conversion between the two. The explicit cast that the compiler suggests will satisfy the compiler, but it will fail at run time because the object returned by OrderBy<T>does not inherit from List<T>.

就理解错误而言,很简单:List<T>不是 的子类型IOrderedEnumerable<T>,因此两者之间没有隐式引用转换。编译器建议的显式转换将满足编译器,但它会在运行时失败,因为 返回的对象OrderBy<T>不继承自List<T>.

EDIT

编辑

An example of List<T>.Sort(Comparison<T>), assuming the type MyTypehas a Keyproperty of some type type T where T : IComparable<T>:

的一个示例List<T>.Sort(Comparison<T>),假设该类型MyType具有Key某种类型 T的属性,其中T : IComparable<T>

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

回答by Ryan P

You need to convert the IEnumerableto a List. Try this:

您需要将 转换IEnumerableList。尝试这个:

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

回答by ASetty

Try this

尝试这个

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

回答by kosa

You need to use LINQ's ToList() method

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

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

You can't cast directly from IEnumerable<> to List<>

你不能直接从 IEnumerable<> 投射到 List<>

回答by BrokenGlass

For sorting a list of strings you do not need Linq in the first place - just use Sort():

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

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

回答by SRQ Coder

OrderBy() is an extension method of IEnumerable - and not List.

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

When the compiler encounters the OrderBy() extension method, it casts the range variable to an IOrderedEnumerable where it can perform the required sorting via CreateOrderedEnumerable method using IComparer et al. Once sorted, the compiler spits out the variable as IEnumerable - usually.

当编译器遇到 OrderBy() 扩展方法时,它会将范围变量转换为 IOrderedEnumerable,在那里它可以使用 IComparer 等人通过 CreateOrderedEnumerable 方法执行所需的排序。排序后,编译器通常会将变量输出为 IEnumerable。

Suggestion: use the var keyword to type 'items' in the LinQ clause.

建议:使用 var 关键字在 LinQ 子句中键入“items”。

Certainly the options offered above using the Sort() and ToList() methods will work - however, using them involves greedy operators and you lose the advantage of lazy loading.

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

Here's a good breakdown here: C# Sort and OrderBy comparisonbetween running Sort() and OrderBy().

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