我知道当我迭代一个IEnumerable时,我会迭代源集合,所以如果我在IEnumerable的下一次迭代中修改了源集合,它就会计算出modificaction。
所以我想知道当我有一个有序的IEnumerable时它会如何影响它。
例如,如果我有这个:
List<MyType> myNoOrderedList //add my items
IEnumerable<MyType> myOrderedIEnumerable = myNoOrderedList
.OrderBy(x => x.Property);
foreach(MyType in myOrderedIEnumerable)
{
//Do something
}
假设我在列表中有3个元素,在IEnumerable的每次迭代中,列表是有序的,还是只列出一次列表?
如果在&#34;做某事&#34;会发生什么?我添加或删除项目? IEnumerable有初始订购的商品,还是必须再次订购以便对帐户进行修改?
答案 0 :(得分:5)
数目:
myOrderedIEnumerable
将无法看到对myNoOrderedList
的任何修改:简化示例:
List<string> initial = new List<String>() {
"a", "z", "e", "d";
};
// Nothing will be done at this point (no ordering)
var ordered = initial.
.OrderBy(x => x.Property);
// ordered has not materialized here, so it'll feel Addition
initial.Add("y"); // <- will be added into ordered
// Here on the first loop ordered will be materialized and since
// initial and ordered are different collection now, we can modify
// initial without changing ordered
foreach (var item in ordered) {
if (item == "a") {
initial.Add("b");
initial.Remove("z");
}
Console.WriteLine(item);
}
结果:
a
d
e
y <- before materialization
z
编辑:请注意,materization是一个棘手的事情:可能会被称为:
.ToList()
,.Any()
,.FirstOrDefault()
.OrderBy
(您的情况).Where()
,.SkipWhile()
- 请参阅Magnus的评论Linq 是懒惰的,并尽可能地实现。
答案 1 :(得分:2)
假设我在列表中有3个元素,在IEnumerable的每次迭代中,列表是有序的,还是只列出一次列表?
根据您当前的代码,只有一次。
每次获得一名普查员时,都会对该名单进行排序
您的foreach
语句将编译为try..finally
,只有一个枚举器将用于迭代收集。
如果在&#34;做某事&#34;会发生什么?我添加或删除项目? IEnumerable有初始订购的商品,还是必须再次订购以便对帐户进行修改?
如果您在从myNoOrderedList
获取枚举数之前在IOrderedEnumerable
添加或删除项目,则会将其包含在已排序的结果中。
如果您在开始枚举已排序的集合后执行此操作,则不会以任何方式影响您的活动枚举,因为已排序的项目已缓冲并从缓冲区返回。
但是,请注意,如果您可以添加或删除项目来枚举集合(在您的情况下为miOrderedIEnumerable
),那么您会得到 InvalidOperationException
#34;收藏被修改;枚举操作可能无法执行&#34;。
答案 2 :(得分:0)
每次需要OrderBy
的结果时,buffered copy of the source is sorted。例如:
int[] array = { 2, 1, 3 };
var ordered = array.OrderBy(x => x);
foreach (int i in ordered)
{
array[1] = 0;
Debug.Write(i); // 123
}
foreach (int i in ordered)
Debug.Write(i); // 023