gpt4 book ai didi

c# - IEnumerable 和 .Where Linq 方法行为?

转载 作者:太空狗 更新时间:2023-10-29 17:47:36 25 4
gpt4 key购买 nike

我以为我知道关于 IEnumerable<T> 的一切但我刚遇到一个我无法解释的案例。当我们在 IEnumerable 上调用 .Where linq 方法时,执行被推迟到对象被枚举,不是吗?

那么如何解释下面的示例:

public class CTest
{
public CTest(int amount)
{
Amount = amount;
}

public int Amount { get; set; }

public override string ToString()
{
return $"Amount:{Amount}";
}

public static IEnumerable<CTest> GenerateEnumerableTest()
{
var tab = new List<int> { 2, 5, 10, 12 };

return tab.Select(t => new CTest(t));
}
}

到目前为止没有什么不好的!但是下面的测试给了我一个意想不到的结果,尽管我对 IEnumerable<T> 有所了解。和 .Where linq 方法:

[TestMethod]
public void TestCSharp()
{
var tab = CTest.GenerateEnumerableTest();

foreach (var item in tab.Where(i => i.Amount > 6))
{
item.Amount = item.Amount * 2;
}

foreach (var t in tab)
{
var s = t.ToString();
Debug.Print(s);
}
}

选项卡中的任何项目都不会乘以 2。输出将是:数量:2数量:5数量:10数量:12

有谁能解释为什么在枚举选项卡后,我得到了原始值。当然,调用.ToList()后一切正常刚调用GenerateEnumerableTest()方法。

最佳答案

var tab = CTest.GenerateEnumerableTest();

tab 是一个 LINQ 查询,它生成 CTest 实例,这些实例从 int 初始化 - 来自整数数组的值永远不会改变。因此,每当您请求此查询时,您都会得到“相同”的实例(具有原始的 Amount)。

如果您想“实现”这个查询,您可以使用 ToList 然后更改它们。否则,您将修改仅存在于第一个 foreach 循环中的 CTest 实例。第二个循环使用未修改的 Amount 枚举其他 CTest 实例。

所以查询包含如何获取项目的信息,你也可以直接调用该方法:

foreach (var item in CTest.GenerateEnumerableTest().Where(i => i.Amount > 6))
{
item.Amount = item.Amount * 2;
}

foreach (var t in CTest.GenerateEnumerableTest())
{
// now you don't expect them to be changed, do you?
}

关于c# - IEnumerable<T> 和 .Where Linq 方法行为?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52951497/

25 4 0