Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# OrderBy和List与iorderenumerable_C#_Linq - Fatal编程技术网

C# OrderBy和List与iorderenumerable

C# OrderBy和List与iorderenumerable,c#,linq,C#,Linq,我遇到了以下代码的意外问题 List<string> items = new List<string>(); items = items.OrderBy(item => item); List items=newlist(); items=items.OrderBy(item=>item); 此代码生成错误: 无法将类型“System.Linq.IORDerenumerable”隐式转换为“System.Collections.Generic.List”。存在显

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

List<string> items = new List<string>();
items = items.OrderBy(item => item);
List items=newlist();
items=items.OrderBy(item=>item);
此代码生成错误:

无法将类型“System.Linq.IORDerenumerable”隐式转换为“System.Collections.Generic.List”。存在显式转换(是否缺少强制转换?)

似乎我可以将
更改为
IEnumerable
类型,错误就会消失。但是我需要能够将项目添加到列表中,
IEnumerable
不支持


有人能帮我理解这个错误吗?最简单的修复方法是什么?简单地强制转换结果安全吗?

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

items = items.OrderBy(item => item).ToList();
试试这个

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

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


您不能直接从IEnumerable强制转换为List

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

List<string> items = GetSomeItems();
items.Sort();
。。。以新顺序创建另一个包含原始项的列表。这仅在您需要出于其他目的保留原始顺序时才有用;这比按顺序排列列表更浪费内存

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

编辑

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

List items=GetSomeItems();
排序((a,b)=>a.Key.CompareTo(b.Key));

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

List items=newlist();
//在此处添加项目
items.Sort();
OrderBy()是IEnumerable-not-List的扩展方法

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

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

当然,上面提供的使用Sort()和ToList()方法的选项会起作用——但是,使用它们会涉及贪婪的操作符,从而失去延迟加载的优势

这里有一个很好的分类:
在运行Sort()和OrderBy()之间。

您首先创建一个空列表,然后尝试对该空列表进行排序?@hvd:当然不是。我在这里所做的是尝试创建一个简单的代码片段,用尽可能少的代码演示问题。但它没有演示问题,因为您删除了太多内容,因此不清楚是否已经有了需要排序的列表,或者你是否有一个枚举,你正在试图排序,并进入一个列表。谢谢。有人知道
ToList()
的效率吗?例如,它是否需要分配一个新集合,然后复制列表中的每一项。@JonathanWood可能。你可以用反射器来找出答案。如果您不需要保留原始列表,我将使用
Sort()
选项。@JonathanWood是的,它会分配一个新列表。但是为什么我需要转换?请解释一下。@Unbreakable,因为.OrderBy不会返回可以隐式转换为列表的内容。谢谢,这似乎是最完整的答案。我喜欢使用
Sort()
的想法,但它不是很方便,因为我的真实数据是一个类,我需要更复杂的排序规则。但我想我总是可以创建一个自定义比较器。@JonathanWood如果类的排序不依赖于上下文,则可以在类上实现
IComparable
,并且
List.Sort()
将使用该实现。还可以将
比较
或lambda
(a,b)=>作为排序函数返回int
(内联或通过传递方法名),这有时更方便。(请参阅:)@JonathanWood在.NET 4中,还有一个
排序
重载,它接受
比较
委托,因此您仍然可以使用lambda表达式。请注意,MSDN:List.Sort-此实现执行不稳定排序;也就是说,如果两个元素相等,它们的顺序可能不会被保留。相反,稳定排序保留ord相等元素的顺序。Enumerable.OrderBy-此方法执行稳定排序;即,如果两个元素的键相等,则保留元素的顺序。相反,不稳定排序不会保留具有相同键的元素的顺序。
List<string> items = GetSomeItems();
items.Sort();
items = items.OrderBy(item => item).ToList(); 
List<MyType> items = GetSomeItems();
items.Sort((a, b) => a.Key.CompareTo(b.Key));
List<string> items = new List<string>();
//add items here
items.Sort();