Question:
many topics on this question. Wondering why sometimes the collection is readonly, and sometimes not. I came across an issue in a netCore 3.1 project where the intention was to modify a collection within a foreach loop. The issue was after the itteration, however the collection was not modified at all… which based on my understanding makes sense.using System;
using System.Diagnostics;
using System.Collections.Generic;
public class Program
{
public static void Main()
{
var iePerson = new[] { new Person(){Id = 2, Name=”SomeName”, Other=5} }; //note other = 5
IEnumerable
DoFoo(pien);
}
private static void DoFoo(IEnumerable
{
foreach(Person p in entities)
{
Console.WriteLine(p.Id);
p.Id = p.Other;
}
foreach(Person p in entities)
Console.WriteLine(p.Id);
//result is
//2
//5 <--- was expecting to see 2...
}
public class Person
{
public string Name {get;set;}
public int Id {get;set;}
public int Other {get;set;}
}
}
[/code]
Answer:
It seems you have a misunderstanding on what aList
is and what an Enumerable
is. The former is a materialized in-memory data-structure, that means a collection of items that exist in memory. You can access the items in that collection by index, add new items or remove items.The latter is just a generalization which states only that you can iterate that collection. However it makes no guarantees about where that data comes from. It might be an in-memory collection such as a list, however it might also be a database or some stream. Which is crucial in your case. Every time you ask your
IEnumerable
to give you the data, it performs a query on the underlying data-store – whatever that might be. In your fiddle that underlying data-storage is an array – something that has already been materialized into memory. In your app however chances are it’s some stream or a database. So when you iterate the enumerable, you execute the query again. This also omits every modification you did in between, because you never transmitted those changes back to the data-storage.Calling
ToList
on your collection (which by the way is not the same as casting) will help to see the changes within your app, as you materialize the data into memory and modify it there. However it won’t help you in saving those changes back into the database.Casting on the other hand won’t change the underlying data-storage. So if it’s already an array, down-casting it to an
IEnumerable
won’t change anything. Of course iterating that enumerable twice will also perform the query twice – but as that storage is an array, that won’t hurt. On a database however, it will hurt much.To keep long stories short:
If you have better answer, please add a comment about this, thank you!