В C # я заметил, что если я запускаю цикл foreach в сгенерированной LINQ коллекции IEnumerable<T>
и пытаюсь изменить содержимое каждого элемента 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