对于每个列表<;T>;扩展方法-值或引用类型
本文关键字:方法 引用类型 扩展 于每个 列表 lt gt | 更新日期: 2023-09-27 18:22:45
我觉得这很奇怪。我想如果有人能澄清我的疑虑。
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
是值类型上的引用类型时
无论c
的类型是引用类型还是值类型,在设置变量c = something
时,都会覆盖引用的变量。因此,c
引用的原始对象不再被引用。不过,这也不会改变列表更新引用的方式,这根本不是它的工作方式。
如果你想用其他东西替换列表中的一些元素,你需要使用Select
:
list.Select(c =>
{
if (SomeCondition)
return new SomeClass();
// default case, return the same element
return c;
}.ToList();
请注意,这会创建一个新列表,因此旧列表仍然包含相同的元素。
如果要实际替换原始列表中的元素,则必须通过访问其索引来覆盖列表中的这些元素。你可以用一个普通的for
循环:
for (int i = 0; i < list.Count; i++)
{
if (SomeCondition)
{
list[i] = new SomeClass();
}
}
这实际上会改变现有列表并替换其中的一些元素