这对我来说似乎很奇怪。想是否有人可以清楚我的怀疑。
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
是值类型
答案 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();
}
}
这实际上会改变现有列表并替换其中的一些元素。