订购了多少次IENumerable?

Álv*_*cía 4 c# ienumerable

我知道当我迭代IEnumerable时,我会迭代源集合,所以如果我在IEnumerable的下一次迭代中修改了源集合,它就会计算modificaction.

所以当我有一个有序的IEnumerable时,我想知道它是如何影响它的.

例如,如果我有这个:

List<MyType> myNoOrderedList //add my items

IEnumerable<MyType> myOrderedIEnumerable = myNoOrderedList
  .OrderBy(x => x.Property);

foreach(MyType in myOrderedIEnumerable)
{
    //Do something
}
Run Code Online (Sandbox Code Playgroud)

假设我在列表中有3个元素,在IEnumerable的每次迭代中,列表是有序的还是只列出一次列表?

如果在"做某事"我添加或删除项目会发生什么?IEnumerable有初始订购的商品还是必须再次订购以便对帐户进行修改?

Dmi*_*nko 5

回答:

  1. 最多一次(如果有的话,在实现上)
  2. 由于您已经实现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);
 }
Run Code Online (Sandbox Code Playgroud)

结果:

a
d
e
y <- before materialization
z 
Run Code Online (Sandbox Code Playgroud)

编辑:请注意,materization是一个棘手的事情:它可能被称为:

  1. 立即,在声明之后.ToList(),例如,之后.Any(),.FirstOrDefault()
  2. 在第一项例如.OrderBy(你的情况)
  3. 决不例如.Where(),.SkipWhile()-见马格努斯的评论

Linq是懒惰和尽可能晚的实现.