Обновление свойства объекта не работает в перечислимом

#c# #list #ienumerable

Вопрос:

Я определил Order класс следующим образом:

 public class Order
{
    public int Id { get; set; }
    public string OrdNumber { get; set; }
}

var dict = new Dictionary<int, string>();
  
dict.Add(1, "ORD1");
dict.Add(2, "ORD2");

var orders = dict.Select(a => new Order { Id = a.Key, OrdNumber = a.Value });
 

Я написал следующий код для обновления Order номера:

 foreach (var ord in orders)
{
    ord.OrdNumber = ord.OrdNumber   "*";
    Console.WriteLine(ord.OrdNumber);
}
 

Код выполняется так, как я ожидаю, вывод будет:

 ORD1*
ORD2*
 

но если я добавлю следующее foreach после foreach показанного выше:

 foreach (var ord in orders)
{
     Console.WriteLine(ord.OrdNumber);
}
 

в результате получается:

 ORD1
ORD2
 

Полный код является :

 var dict = new Dictionary<int, string>();
dict.Add(1, "ORD1");
dict.Add(2, "ORD2");

var orders = dict.Select(a => new Order { Id = a.Key, OrdNumber = a.Value });

foreach (var ord in orders)
{
   ord.OrdNumber = ord.OrdNumber   "*";
   Console.WriteLine(ord.OrdNumber);
}

foreach (var ord in orders)
{
   Console.WriteLine(ord.OrdNumber);
}
 

и результат таков :

 ORD1*
ORD2*
ORD1
ORD2
 

Добавление .ToList() в конец следующей строки:

 dict.Select(a => new Order { Id = a.Key, OrdNumber = a.Value })
 

устраняет проблему. Теперь результат будет:

 ORD1*
ORD2*
ORD1*
ORD2*
 

Кто-нибудь может объяснить, почему это происходит?

Ответ №1:

.Select() возвращает a IEnumerable , который является воспроизведением последовательности, в вашем случае, a => new Order { Id = a.Key, OrdNumber = a.Value }

Каждый раз , когда вы будете foreach IEnumerable , вы будете воспроизводить эту последовательность.

Теперь при добавлении .ToList() его материализуйте последовательность в списке, создавая и сохраняя объекты. Когда вы foreach составляете список, вы воспроизводите не последовательность его создания, а то, что на самом деле содержат его значения, вот почему в этом случае ord.OrdNumber = ord.OrdNumber "*"; при использовании List