【发布时间】:2011-11-09 11:32:45
【问题描述】:
在 C# 中,我注意到如果我在 LINQ 生成的IEnumerable<T> 集合上运行 foreach 循环并尝试修改每个 T 元素的内容,我的修改不会持久。
另一方面,如果我在创建集合时应用ToArray() 或ToList() 方法,则对foreach 循环中各个元素的修改是持久的。
我怀疑这在某种程度上与延迟执行有关,但具体如何对我来说并不完全清楚。我真的很感激对这种行为差异的解释。
这里是一些示例代码 - 我有一个类 MyClass 带有一个构造函数和自动实现的属性:
public class MyClass
{
public MyClass(int val) { Str = val.ToString(); }
public string Str { get; set; }
}
在我的示例应用程序中,我使用 LINQ Select() 根据整数集合创建两个 MyClass 对象集合,一个 IEnumerable<MyClass> 和一个 IList<MyClass>,最后应用 ToList() 方法。
var ints = Enumerable.Range(1, 10);
var myClassEnumerable = ints.Select(i => new MyClass(i));
var myClassArray = ints.Select(i => new MyClass(i)).ToList();
接下来,我对每个集合运行一个 foreach 循环,并修改循环的 MyClass 对象的内容:
foreach (var obj in myClassEnumerable) obj.Str = "Something";
foreach (var obj in myClassArray) obj.Str = "Something else";
最后,我输出每个集合中第一个元素的Str 成员:
Console.WriteLine(myClassEnumerable.First().Str);
Console.WriteLine(myClassArray.First().Str);
有点反直觉,输出是:
1
Something else
【问题讨论】:
-
编辑了帖子以保持一致性。 FWIW,使用
MyClass[] arr = enumerable.ToArray()时也是如此。现在为了真正的乐趣,请尝试使用struct MyStruct { ... }代替 :) -
谢谢,谢。是的,我有点猜到 struct 无论如何都不是一个选项。
标签: c# foreach reference ienumerable