C# 列表';s ForEach()方法未按预期运行

C# 列表';s ForEach()方法未按预期运行,c#,foreach,C#,Foreach,为什么这不起作用 List<int> test = new List<int>(); for (int i = 0; i < 20; ++i) test.Add(i); test.ForEach(t => t = ++t); List test=newlist(); 对于(int i=0;it=++t); 测试中的元素不会递增。整数是值,而不是引用 另外,foreach不允许操纵集合元素 恐怕这是双重失败:( 什么是有效的: for(int i

为什么这不起作用

List<int> test = new List<int>();
for (int i = 0; i < 20; ++i)
    test.Add(i);

test.ForEach(t =>  t = ++t);
List test=newlist();
对于(int i=0;i<20;++i)
测试。添加(i);
test.ForEach(t=>t=++t);

测试中的元素不会递增。

整数是值,而不是引用

另外,foreach不允许操纵集合元素

恐怕这是双重失败:(

什么是有效的:

for(int i=0;i<test.Count;i++)
    test[i]++;

for(int i=0;iint是值,而不是引用

另外,foreach不允许操纵集合元素

恐怕这是双重失败:(

什么是有效的:

for(int i=0;i<test.Count;i++)
    test[i]++;
首先,for(inti=0;i不是LINQ的一部分。它从2.0开始就出现在.NET中

测试中的元素不会递增

不,它们不会是。
Action
的参数是通过值传递的,而不是通过引用传递的。对参数所做的更改(
t
在您的情况下)对调用代码是不可见的,即使是可见的,也不能保证
List.ForEach
会使用它们

请注意,如果将引用类型(例如
StringBuilder
)作为列表元素类型,并对参数值引用的对象中的数据进行了更改,例如

builders.ForEach(x => x.Append("Foo"))
然后,这些更改将在列表中可见,因为它们根本不是对列表的更改-列表将包含与以前相同的引用,只是对数据发生更改的对象的引用。

首先,它不是LINQ的一部分。它从2.0开始就在.NET中

测试中的元素不会递增

不,它们不会是。
Action
的参数是通过值传递的,而不是通过引用传递的。对参数所做的更改(
t
在您的情况下)对调用代码是不可见的,即使是可见的,也不能保证
List.ForEach
会使用它们

请注意,如果将引用类型(例如
StringBuilder
)作为列表元素类型,并对参数值引用的对象中的数据进行了更改,例如

builders.ForEach(x => x.Append("Foo"))

然后,这些更改将在列表中可见,因为它们根本不是对列表的更改-列表将包含与以前相同的引用,只是对数据发生更改的对象的引用。

您拥有的
t
变量是列表中项的副本。您正在修改副本,因此也就是lis中的项t本身不受影响。要增加列表中的每个项目,可以使用
for
循环:

for(int i = 0; i < test.Count;i++
    test[i]++;
for(int i=0;i
您拥有的
t
变量是列表中项目的副本。您正在修改副本,因此列表中的项目本身不受影响。要增加列表中的每个项目,可以使用
for
循环:

for(int i = 0; i < test.Count;i++
    test[i]++;
for(int i=0;i
这是预期结果

您不会期望以下内容在
Main
中实际递增
x
,因此您的lambda示例也不例外

static void Main(string[] args)
{
    int x = 1;
    Increment(x);
    Console.WriteLine("{0}");
}

static void Increment(int x)
{
    x = ++x;
}

这是预期的结果

您不会期望以下内容在
Main
中实际递增
x
,因此您的lambda示例也不例外

static void Main(string[] args)
{
    int x = 1;
    Increment(x);
    Console.WriteLine("{0}");
}

static void Increment(int x)
{
    x = ++x;
}
List test=newlist();
对于(int i=0;i<20;++i)
测试。添加(i);
对于(var z=0;z
列表测试=新列表();
对于(int i=0;i<20;++i)
测试。添加(i);
对于(var z=0;z
只需将您的值包装到一个类中即可。如果您需要1到20的范围,则更容易使用
Enumerable.range(1,20)
@FelixK。只使用
循环比使用
循环要容易得多。还要注意,类语义在他的代码中的其他地方可能并不可取。另一个你应该避免
列表的原因。ForEach
…你可能有副作用的概念让人困惑。只需将你的值包装到一个类中。如果你需要1到20个range,更容易使用
可枚举范围(1,20)
@FelixK。只使用
进行
循环要比通过循环容易得多。还要注意,类语义在他的代码中的其他地方可能不可取。你应该避免使用
列表的另一个原因。ForEach
…你可能会有副作用的概念让人困惑。感谢你的回答,我知道其他选择,但我确实知道我很好奇为什么这不起作用,今天我在工作中偶然发现了它,在使用linq和sql这么长时间后,我没有意识到我使用的是像int这样的原语。谢谢你的回答,我知道其他选择,但我很好奇为什么这不起作用,在使用linq和sql这么长时间后,我今天在工作中偶然发现了它我没有意识到我在使用int这样的原语。谢谢