C#Foreach和for之间的差异(非性能)
C#Foreach和for之间的差异(非性能),c#,visual-studio-2008,foreach,C#,Visual Studio 2008,Foreach,不久前,我读到foreach处理对象的“副本”,因此它可以用于信息检索而不是更新。我不明白,因为完全可以循环遍历类列表并更改其字段。谢谢 您可能已经了解到,在使用foreach对集合进行迭代时不能修改集合,而可以(如果小心的话)使用for循环。例如: using System; using System.Collections.Generic; class Test { static void Main() { var list = new List<in
不久前,我读到foreach处理对象的“副本”,因此它可以用于信息检索而不是更新。我不明白,因为完全可以循环遍历类列表并更改其字段。谢谢 您可能已经了解到,在使用
foreach
对集合进行迭代时不能修改集合,而可以(如果小心的话)使用for
循环。例如:
using System;
using System.Collections.Generic;
class Test
{
static void Main()
{
var list = new List<int> { 1, 4, 5, 6, 9, 10 };
/* This version fails with an InvalidOperationException
foreach (int x in list)
{
if (x < 5)
{
list.Add(100);
}
Console.WriteLine(x);
}
*/
// This version is okay
for (int i = 0; i < list.Count; i++)
{
int x = list[i];
if (x < 5)
{
list.Add(100);
}
Console.WriteLine(x);
}
}
}
使用系统;
使用System.Collections.Generic;
课堂测试
{
静态void Main()
{
var list=新列表{1,4,5,6,9,10};
/*此版本失败,出现InvalidOperationException
foreach(列表中的int x)
{
if(x<5)
{
增加(100);
}
控制台写入线(x);
}
*/
//这个版本还可以
for(int i=0;i
如果这不是您所指的内容,请提供更多详细信息-在不确切了解内容的情况下,很难解释您所阅读的内容。您无法修改
foreach
中的元素:
var list = new List<string>();
list.AddRange(new string[] { "A", "B", "C" });
foreach (var i in list)
{
// compilation error: Cannot assign 'i' because it is a 'foreach iteration variable'
i = "X";
}
var list=newlist();
AddRange(新字符串[]{“A”、“B”、“C”});
foreach(列表中的变量i)
{
//编译错误:无法分配“i”,因为它是“foreach迭代变量”
i=“X”;
}
尽管在使用
for
时,您访问的是列表中的元素及其索引,而不是迭代器,因此您可以通过这种方式修改集合。foreach使用迭代器获取序列中的每个元素。序列可以是实现IEnumerable的任何内容。IEnumerable不需要是有限的(序列0 1 2 3 4…1000…)是IEnumerable
for只是一个C#构造,它允许您声明一个循环(用于执行所有类型的操作,而不仅仅是迭代集合)
值得注意的是,集合的.NET中的迭代器实现不支持迭代期间的序列修改
foreach
正在使用IEnumerable
循环收集。这使得无法修改此集合(删除、添加项),但仍然可以修改其中的对象(如果它们是引用类型)
for
是简单循环与直接访问集合中项目的简单组合。此循环运行时没有任何类型的阻塞。将其与只读字段进行比较:
private readonly List<int> MyList = new List<int>();
最后,如果正在使用基础集合,则不要求用于实现foreach的枚举数保持有效:
foreach(int x in SomeEnumerable)
{
if(x != 0)
SomeEnumerable.Add(0);
}
假设
Add
修改了SomeEnumerable
,那么上面的可能会起作用,它可能会以一种奇怪而难以理解的方式“起作用”,并且可能会引发异常。此类代码不能保证任何行为,因此,在枚举期间修改集合被认为是不正确的。Jon,谢谢。是的,我阅读了它,并且理解如果循环通过它,我不能删除例如数组的元素。但我认为我可以修改每个元素的内容,对吗?另一个警告是foreach的实现可能与for()使用的索引器非常不同。对于listview的SelectedItems集合,它在性能方面有很大的不同。@Radusko:是的,您可以修改所引用对象中的数据。。。尽管它是值类型,但您仍然需要处理副本。(希望您不必处理可变值类型。)@Jon Skeet:谢谢。不,这些不是值类型,我指的是类。我只是想确定我是否理解了。@Jon Skeet:但是,如果我循环遍历字符串数组,我将无法更改它。字符串是不可变的,但引用是不可变的,这就是原因?实际上,您可以修改作为引用类型的元素(如果可以修改的话)。您不能替换、添加或删除它们。代码无法工作的原因是字符串是不可变的。一旦创建了字符串,就不能以任何方式修改它。看起来是修改的内容实际上是用一个字符串替换另一个字符串。因此,在上面给出的示例中,您替换了其中一个元素(或删除一个元素并添加一个元素),并且在枚举集合时不允许这样做。
foreach(int x in SomeEnumerable)
{
if(x != 0)
SomeEnumerable.Add(0);
}