C # foreach em IEnumerable vs. List - modificação de elemento persistente apenas para array - Por qu

Em C #, notei que, se estou executando um loop foreach em um LINQ geradoIEnumerable<T> coleção e tente modificar o conteúdo de cada elemento T, minhas modificaçõesnão sã persistente.

Por outro lado, se eu aplicar oToArray() ouToList() método ao criar minha coleção, modificação dos elementos individuais no loop foreachestamo persistente.

Suspeito que isso esteja relacionado à execução adiada, mas exatamente como isso não é totalmente óbvio para mim. Eu realmente aprecio uma explicação para essa diferença de comportament

Aqui está um código de exemplo - eu tenho uma classeMyClass com um construtor e uma propriedade implementada automaticamente:

public class MyClass
{
    public MyClass(int val) { Str = val.ToString(); }
    public string Str { get; set; }
}

No meu exemplo de aplicativo, eu uso o LINQSelect() para criar duas coleções deMyClass objetos baseados em uma coleção de números inteiros, umIEnumerable<MyClass>, e umIList<MyClass> aplicando oToList() no fina

var ints = Enumerable.Range(1, 10);
var myClassEnumerable = ints.Select(i => new MyClass(i));
var myClassArray = ints.Select(i => new MyClass(i)).ToList();

Em seguida, corro um loop foreach sobre cada uma das coleções e modifico o conteúdo do @ looped ovMyClass objetos:

foreach (var obj in myClassEnumerable) obj.Str = "Something";
foreach (var obj in myClassArray) obj.Str = "Something else";

Finalmente, eu mostro oStr membro do primeiro elemento de cada coleção:

Console.WriteLine(myClassEnumerable.First().Str);
Console.WriteLine(myClassArray.First().Str);

Um pouco contra-intuitivamente, a saída é:

1
Something else

questionAnswers(2)

yourAnswerToTheQuestion