鉴于:
// got a dictionary wrapped in a class - reading values into list
List<string> caplist = QuizData.Dict.Values.ToList();
// shuffle cap list - I know it's not "really random"
var rnd = new Random();
var shufcapList = caplist.OrderBy(item => rnd.Next());
// take first fifteen from shuffled list for caps choices
var firstFifteenItems = shufcapList.Take(15);
foreach (string cap1 in firstFifteenItems) {
Console.WriteLine("1st_15"+cap1); //seems OK
}
// take first 6 from firstFifteenItems (it's been shuffled) list for states
var firstSixItems = firstFifteenItems.Take(6);
foreach (string cap2 in firstSixItems) {
Console.WriteLine("1st_6" + cap2);
}
但是firstSixItems不是firstFifteenItems的子集。不是吗我在看控制台输出的firstFifteenItems中计数了15个项目。我从firstSixItems计数了6个项目,但这些项目不在firstFifteenItems中。我想非破坏性地将一个列表中的前6个项目复制到另一个列表中。我缺少明显的东西吗?感谢帮助。
最佳答案
这里的“问题”是懒惰的评估。
这些可枚举在枚举之前不会进行评估。在此之前,通过调用IEnumerable
返回的OrderBy
只是一组有关如何检索元素的指令,但是实际上还没有任何结果。直到Take(15)
循环才真正评估对foreach
的调用。
对Take(6)
的调用在其后面的foreach
中进行评估,但这是从firstFifteenItems
派生的可枚举对象,它本身是原始OrderBy
的惰性枚举,因此它再次调用rnd.Next()
多次。 。当然,每次调用rnd.Next()
都会返回一个(可能)不同的结果。
在ToList()
上调用OrderBy
,您将看到预期的行为,因为ToList()
将枚举并存储结果。