我注意到一些有趣的事情。我可以在 foreach 块中更改数组的元素或分配新的数组引用,但我无法对集合执行相同的操作,它会给出错误。为什么? 以下示例给出错误
List<string> isimler = new List<string>() { "Ali", "Ayşe", "Fatma", "Mehmet" };
foreach (var (isim, index) in isimler.Select((isim, index) => (isim, index)))
{
isimler[index] += 10;
}
foreach(string isim in isimler)
{
Console.WriteLine(isim);
}
以下示例没有给出错误,它正在工作
string[] isimler = { "Ali", "Ayşe", "Fatma", "Mehmet" };
foreach (var (isim, index) in isimler.Select((isim, index) => (isim, index)))
{
isimler[index] += 10;
}
foreach(string isim in isimler)
{
Console.WriteLine(isim);
}
因为列表有用于显式跟踪的代码(每次通过列表 API 进行更改时都会更改跟踪整数),而数组没有。对于列表,这一点尤其重要,因为如果您添加或删除元素,可能会对循环的行为产生重大不利影响(例如,想象一下删除第零个元素)。由于您无法使用数组添加/删除,因此这不太令人担忧,并且数组旨在作为非常原始的数据类型,没有此类额外跟踪字段的开销。
碰巧的是,您可以使用一些 API来避免注意到
List<T>
这个特定的更改。但这并不是一个好主意!如果你要这么做的话,效率会更高:
但最终,无论发生哪种情况:如果在您查看某个事物时,其内容正在发生变化:则无论是否被注意到,都存在危险的事情发生。
的行为
List
更多的是一个实现细节(尽管在大多数情况下这是一个好主意 -Add/Remove
正如Mark Gravell的回答所描述的,它涉及许多事情)。关于这个问题我能找到的最官方的资料是这样的:
因此,列表会抛出异常,而数组不会。没有什么可以真正阻止您创建一个集合,该集合
IEnumerable
在修改时实现和行为与数组类似,但List
在您尝试添加或删除元素时(抛出异常)就像数组一样。