gpt4 book ai didi

c# - 为什么 Select 会将我的 while 循环变成无限循环?

转载 作者:太空狗 更新时间:2023-10-29 20:22:43 26 4
gpt4 key购买 nike

在工作中我遇到了一个奇怪的问题,我期望终止的循环实际上无限期地运行

我将问题追溯到 Select 的使用。有趣的是,当我在 Select 之后添加 .ToList() 时,循环终止。我把它归结为一个小例子。

class WrappedBool
{
public WrappedBool(bool inner)
{
InnerBool = inner;
}
public bool InnerBool { get; set; } = false;
}

// remove .ToList() here and the following loop will go infinite
IEnumerable<WrappedBool> enumerable =
new List<bool>() { false, true, false }
.Select(b => new WrappedBool(b))
.ToList();

while (enumerable.Any(wb => !wb.InnerBool))
{
WrappedBool firstFalse = enumerable.Where(wb => !wb.InnerBool).First();
firstFalse.InnerBool = true;
}

虽然我不必再处理我的代码不再终止,但我仍然想知道这种行为最初是从哪里来的。

最佳答案

嗯,没有物化 ( .ToList() ) enumerable只是一个查询

IEnumerable<WrappedBool> enumerable = 
new List<bool>() { false, true, false }
.Select(b => new WrappedBool(b));

无论何时调用它,它都会创建一个 List<bool>() {false, true, false}新实例你在哪里false迭代的项目

// new List<bool>() { false, true, false } - do we have any false item here?
// Yes - keep on looping (forever)
while (enumerable.Any(wb => !wb.InnerBool))
{
// get 1st false from new List<bool>() { false, true, false }
WrappedBool firstFalse = enumerable.Where(wb => !wb.InnerBool).First();
// turn it into true and discard
firstFalse.InnerBool = true;
}

相反

IEnumerable<WrappedBool> enumerable = 
new List<bool>() { false, true, false }
.Select(b => new WrappedBool(b))
.ToList(); // create a List; call new List<bool>() { false, true, false } just once

物化所以enumerableList<T>它创建一次,您可以在其中修改第一个和第三个项目:

// does enumerable collection (List) have any false item? 
while (enumerable.Any(wb => !wb.InnerBool))
{
// get 1st false from enumerable List
WrappedBool firstFalse = enumerable.Where(wb => !wb.InnerBool).First();
// turn it into true
firstFalse.InnerBool = true;
}

关于c# - 为什么 Select 会将我的 while 循环变成无限循环?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57357702/

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