ForEach List <t>扩展方法 - 值或参考类型?

时间:2015-11-20 09:20:08

标签: c# linq collections

这对我来说似乎很奇怪。想是否有人可以清楚我的怀疑。

var list = new List<SomeClass>();

现在,如果我们使用ForEach集合的扩展方法

list.ForEach(c=>c.SomeProperty = SomeValue);

所以现在我们可以获得更新的价值。所以它似乎是参考类型。是的ForEach需要Action所以它的引用类型。但是如果尝试重新启动ForEach内的对象,我看不到预期的行为。

list.ForEach(c=>{
  if(SomeCondition) // lets consider its always true now.
  {
    c = new SomeClass();
  }
});

所以在执行之后,我期待新的清单。并且不应该包含旧对象的引用。但如果我打印清单。我可以看到旧的价值观。

那么为什么ForEach没有重新初始化列表中的对象?虽然我们看到ForEach是值类型

的引用类型

1 个答案:

答案 0 :(得分:1)

无论c的类型是引用类型还是值类型,在设置变量c = something时,都会覆盖所引用的变量。因此不再引用c引用的原始对象。这并不会改变列表更新其引用,但这根本不是它的工作原理。

如果您想用其他内容替换列表中的某些元素,则需要使用Select

list.Select(c =>
{
    if (SomeCondition)
        return new SomeClass();

    // default case, return the same element
    return c;
}.ToList();

请注意,这会创建一个 new 列表,因此旧列表仍包含相同的元素。

如果要实际替换原始列表中的元素,则必须通过访问其索引来覆盖列表中的元素。您可以使用正常的for循环执行此操作:

for (int i = 0; i < list.Count; i++)
{
    if (SomeCondition)
    {
        list[i] = new SomeClass();
    }
}

这实际上会改变现有列表并替换其中的一些元素。