c# - 更改枚举项在原始 IEnumerable 中未更改
问题描述
我注意到枚举集合的问题,这是因为.Select<T>()
我可以枚举它,并修改集合中的每个项目。当我在枚举完成后查看集合时,每个项目都未修改。
public class FooModel
{
public Guid? Id { get; set; }
}
[TestClass]
public class UnitTest1
{
[TestMethod]
public void TestMethod1()
{
IEnumerable<FooModel> foos = Enumerable.Range(0, 100)
.Select(m => new FooModel());
foreach(FooModel f in foos)
{
f.Id = Guid.NewGuid();
}
Assert.IsTrue(foos.All(foo => foo.Id.HasValue));
}
}
如果我追加.ToList()
或.ToArray()
执行可枚举,那么它会修改集合中的项目。
我知道IEnumerable
没有在 之后执行.Select<T>
,但是在foreach
运行时它会创建一个枚举器并在 foo 本地字段上执行 IEnumerable。为什么它不引用Select<T>
创建的相同对象?
我已经看到有关何时使用IEnumerable
over的问题,List
但我了解两者之间的区别。或多或少地描述与实施。我的问题更多是关于为什么 foreach 在本地字段上执行 IEnumerable 并且不对本地变量中引用的相同对象进行操作。
解决方案
为什么它不引用 Select 创建的同一对象?
因为foo
正在使用Enumerable.Range
which enumerates on-the-fly。没有您要迭代的基础数据存储。
当您调用时,foreach
您正在执行底层查询,它会动态创建 100 个FooModel
对象,您可以对其进行修改。
当您调用 时.All
,您会再次执行查询,这会动态创建另外100 个尚未修改的Foo
对象。
当您通过or对结果进行水合时,您将循环一个具体的集合,并且您对基础对象的更改将持续存在。ToList
ToArray
推荐阅读
- python - 如何从其他表 django rest 框架中获取数据
- javascript - 当特定条件以角度为真时如何显示和隐藏数据
- python - Python 多处理变得越来越慢。为什么?
- c# - 我们真的需要将 .NET 框架升级到 .NET Core
- python - 将字符串数组的 pyspark 列转换为数据块上的字符串时出错
- shell - 使所有首选列元素为零
- python - Django:在models.py中添加`__str__`函数不起作用
- javascript - 通过检查每个动态创建的文本框是否为空来防止表单提交
- sql - 如何用日期而不是 SQL 中的行计算 7 天平均值?
- unity3d - Unity 2D 重叠碰撞器