n
是你的当前值的列表中的一个副本不是要操纵你的列表中的值,以你的值。如果一个参考,然后用一个for循环
for(int i = 0; i<numbers.Count; i++)
numbers[i] *= 5;
更详细的解释:
与正常的foreach
循环你的代码甚至不编译:
foreach(var n in numbers)
n = n * 5; // Readonly local variable cannot be used as an assignment target
记住循环是不一样的foreach
但它只是需要一个Action<int>
委托作为参数,并执行指定的动作的每一个元素的方法,你list.So它执行像这样(摘自源代码):
public void ForEach(Action<T> action)
{
// removed unnecessary parts for brevity
for(int i = 0 ; i < _size; i++)
{
action(_items[i]);
}
}
正如你可以在这里看到的_item[i]
传递到行动,因为int是你的价值的副本传递值类型,而不是一个reference.And这就是为什么你的价值观没”改变。
对于字符串:除了一个事实,即字符串是不可改变的,分配一个新的参考引用类型并不改变持有相同reference.For例如考虑这个对象:
static void Update(string s)
{
s = "bar";
}
string f = "foo";
Update(f);
Console.WriteLine(f); // foo
分配一个对s
的新引用不会更改f
,f
stil保留旧的引用,s
指向内存中的新位置。这不是因为s
是副本,它不是。如果更改s
的某个属性(使用字符串你不能这样做,但尝试使用另一个参考类型),它也会更新f
的属性。它工作在这种方式,因为s
和f
都指向同一位置memory.So s
。你可以把两个不同的字符串没有被绑定到f
他们声明如下:
string f = "foo";
string s = f;
s = "bar";
唯一的例外是当你通过f
作为ref
参数,则该任务将改变f
还有:
static void Update(ref string s)
{
s = "bar";
}
string f = "foo";
Update(ref f);
Console.WriteLine(f); // bar
这是因为整数是值类型,并通过值而不是通过引用传递。 – 2014-09-25 23:21:07
我使用字符串得到相同的结果。我无法修改ForEach循环内的字符串。 – Ricardo 2014-09-25 23:22:12
@Ricardo真的吗?你正在执行什么操作? – BradleyDotNET 2014-09-25 23:23:01