With great surprised I observed the following behavior today: Given a class
class Foo
{
prop int FooNumber { get; set; }
}
and this code
IEnumerable<Foo> foos = Enumerable.Range(0,3).Select(new Foo());
foreach (var foo in foos)
foo.Bar = 5;
foreach (var foo in foos)
Console.Write(foo.Bar); // Writes 000
while initializing foos to new List<Foo>{ new Foo(), new Foo(), new Foo() } makes the loop write “555”.
My question: Why does this happen and is there a way to circumvent this whithout using .ToList() (which needs a comment, since it does not seem to be needed here).
It happens because
foosis dynamically produced each time you enumerate it. So during the first iteration you are setting property values on objects that are no longer referenced by anything after the iteration ends. The second iteration works on freshly constructed objects which have the default property value.Initializing
foosto a list of “persistent” objects changes things, as does using.ToList()for the same reason (a “fixed” list is constructed and iterated over twice; the original dynamically producedIEnumerableis only iterated over once).Having established that you should use
.ToList()here: in general I do not feel that it needs a comment because it is not customary to iterate over dynamically produced sequences more than once (I believe many code analysis tools warn against this), but by all means do write one.