【问题标题】:Updating an object property doesn't work in an enumerable更新对象属性在可枚举中不起作用
【发布时间】:2021-11-29 11:26:21
【问题描述】:

我定义了一个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*

谁能解释为什么会这样?

【问题讨论】:

    标签: c# list ienumerable


    【解决方案1】:

    .Select() 返回一个IEnumerable,这是一个序列播放,在你的情况下,a =&gt; new Order { Id = a.Key, OrdNumber = a.Value }

    每次你foreachIEnumerable,你都会播放那个序列。

    现在,当添加.ToList() 时,它物化列表中的序列,通过创建和保留对象。当您 foreach 列表时,您不会播放它的创建顺序,而是播放它的实际值,这就是为什么在这种情况下 ord.OrdNumber = ord.OrdNumber + "*"; 在使用 List 时保持不变

    【讨论】:

      猜你喜欢
      • 2017-07-12
      • 1970-01-01
      • 2010-09-23
      • 2018-12-18
      • 1970-01-01
      • 2017-03-05
      • 1970-01-01
      相关资源
      最近更新 更多