gpt4 book ai didi

c# - 使用 list 中的 take 方法后的 Removerange 方法出现意外行为

转载 作者:太空宇宙 更新时间:2023-11-03 19:41:28 29 4
gpt4 key购买 nike

有谁知道为什么在下面的代码中离开 while 循环体后的长度为零?请不要向我提供分块算法我已经知道了几种这样的算法并且我知道如何解决这个问题。我的问题只是关于 RemoverRange 或 Take 的有线行为。

static void Main(string[] args)
{

var list = new List<int>();
for (int i = 0; i < 1000; i++)
{
list.Add(i);
}

var chunks = new List<IEnumerable<int>>();

while (list.Count > 0)
{
chunks.Add(list.Take(10));
list.RemoveRange(0, 10);
}

int length = chunks.ToList()[0].Count();
}

最佳答案

在以下行:

var chunks = new List<IEnumerable<int>>();

您创建了一个列表,其 Count为 0,因为列表中没有任何项目。然后在 foreach在每一步添加声明 list.Take(10)之后,您从 list 中删除前 10 项.这里的重要是意识到list.Take(10)惰性评估(您更经常听到术语延迟执行)。首次评估的时间在以下行:

int length = chunks.ToList()[0].Count();

在这一行 list.Take(10)将被评估,因为您已经删除了 list 中的所有项目, list 中没有任何元素.为此,list.Take(10)返回一个空序列,因此返回 chunks.ToList()[0]将是一个空列表。

更新 延迟执行解释:

让我们有以下列表:

var list = new List<int> {1, 2, 3, 4, 5 };
var firstThree = list.Take(3);

变量firstThree持有对枚举器的引用 - 特别是 IEnumerable<int> .它不包含数组或 1、2、3 的列表。第一次使用此迭代器时,您将开始从 list 中“获取”数据。 .

例如,您可以调用 ToListToArray方法:

var firstThreeList = firstThree.ToList();
var firstThreeArray = firstThree.ToArray();

上述两个调用都会使迭代器起作用——一般来说会强制在 LINQ 中执行您的查询。此时此刻,你将遍历 list您将获取前三项。

话虽如此,很明显,如果您同时修改了 list通过从 iist 中删除所有数字, list 中不会有任何元素你什么也得不到。

作为测试,我建议您运行一次上面的代码然后再次运行它但是ToList之前和 ToArray调用电话:

list.RemoveAll(x => true);

现在您会注意到 firstThreeArrayfirstThreeList是空的。

关于c# - 使用 list<T> 中的 take 方法后的 Removerange 方法出现意外行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52735390/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com