gpt4 book ai didi

c# - IEnumerable 中的项目在 foreach 内部发生了更改,但更改未保存到集合中

转载 作者:行者123 更新时间:2023-11-30 13:19:07 28 4
gpt4 key购买 nike

我今天遇到了一个有趣的问题,这是一个重现:

class TestListAndEnumerable
{
public static void Test()
{
bool b1 = GetBool1(); // returns false
bool b2 = GetBool2(); // returns true
}

private static bool GetBool1()
{
IEnumerable<BoolContainer> list = new List<bool> { false }.Select(x => new BoolContainer { Value = x });

foreach (BoolContainer item in list)
{
item.Value = true;
}

return list.Select(x => x.Value).First();
}

private static bool GetBool2()
{
List<BoolContainer> list = new List<bool> { false }.Select(x => new BoolContainer { Value = x }).ToList();

foreach (BoolContainer item in list)
{
item.Value = true;
}

return list.Select(x => x.Value).First();
}

private class BoolContainer
{
public bool Value { get; set; }
}
}

GetBool1() 中,改变 item 的值对 list 变量没有影响。
GetBool2() 按预期工作。

有人知道为什么会这样吗?

[关于重复标签]

我认为这与 this question 中的问题基本相同, 但这里的问题更简洁切中要害,所以我将保留它。

最佳答案

这是LINQ惰性求值的问题。每次迭代 listGetBool1() ,您正在创建一个新的值序列。更改 Value这些对象之一的属性不会改变任何其他内容。

将其与 GetBool2() 进行比较, 你接到一个电话 ToList() ,这意味着您正在创建一个 List<T>包含一系列对象。现在,每次遍历该列表时,您都会获得对相同对象的引用……因此,如果您修改其中一个对象中的值,下次就会看到。

如果您更改 Select argument

x => { Console.WriteLine("选择!");返回新的 BoolContainer { Value = x } };

... 然后添加适当的额外 Console.WriteLine调用以便您可以看到它何时发生,您会看到从未在 GetBool2() 中调用委托(delegate)在调用 ToList() 之后, 但在 GetBool1()每次迭代序列时都会调用它。

关于c# - IEnumerable 中的项目在 foreach 内部发生了更改,但更改未保存到集合中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30413423/

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