我在c#中有以下代码段。
var list = new List<string> { "a", "b", "c" };
for (int i = 0; i < list.Count; i++)
{
list.Add(list[i].ToUpper());
}
上面的代码中没有编译时错误,但我在运行时遇到System.OutOfMemoryException
异常?
答案 0 :(得分:10)
List.Count
都会重新评估。
所以,你有3个元素。在for循环的第一次迭代之后,您将Count
== 4.因此i
永远不会达到Count
值(直到整数溢出情况,但在您的情况下,内存不足)
你可以写smth。像:
var listInUpperCase = list.Select(x => x.ToUpper())
.ToList();
list.AddRange(listInUpperCase);
答案 1 :(得分:4)
循环的每次迭代都会添加一个项目。循环的上限(list.Count
)增加。你继续循环。最终,你的内存不足。
要解决您的问题,请事先获取计数。
int count = list.Count;
for (int i = 0; i < count; i++)
{
答案 2 :(得分:2)
在每次迭代时评估循环条件list.Count
。
由于它每次迭代增加一次(你向该列表添加一个元素),你的代码将无休止地循环,直到它最终耗尽内存。
如果要用大写等效项替换每个元素,可以使用以下代码:
var list = new List<string> { "a", "b", "c" };
for (int i = 0; i < list.Count; i++)
{
list[i]=list[i].ToUpper();
}
// list contains {"A", "B", "C"}
如果您真的想要添加到列表中,可以将计数存储在本地变量中:
var list = new List<string> { "a", "b", "c" };
int count=list.Count;
for (int i = 0; i < count; i++)
{
list[i]=list[i].ToUpper();
}
// list contains {"a", "b", "c", "A", "B", "C"}
答案 3 :(得分:1)
你的循环永远不会结束,因为Count是通过循环每次迭代计算的,并且你在循环中每次迭代都会增加Count。由于我从0开始,你将无限期地添加项目,直到你的内存不足为止。
答案 4 :(得分:1)
看起来你在列表中添加了一个新项目,因此无论整数的最大值是什么,我都不会达到列表计数和最大值。
答案 5 :(得分:1)
这是一个无限循环。您将继续永久地向列表中添加元素。 i
从0开始,列表以3个元素开头。每次迭代中每个都增加1,因此i
永远不会赶上。当列表不可避免地消耗所有可用内存时,就会发生异常。
答案 6 :(得分:1)
您正在将列表循环到最后,同时向其中添加项目。所以永远不会达到目的。我想你的意思是:
var list = new List<string> { "a", "b", "c" };
for (int i = 0; i < list.Count; i++)
{
list[i] = list[i].ToUpper();
}
答案 7 :(得分:1)
因为for循环在i < list.Count
期间继续发生,因为你在每次迭代中都添加了一个新项目。使用另一个列表作为大写字符串,或者在开始循环之前计算一次:
int length = list.Count;
for (int i=0; i<length; i++)
...
答案 8 :(得分:1)
因为你正在改变循环体中的计数器值!它永远不会结束。
var list = new List<string> { "a", "b", "c" };
for (int i = 0; i < list.Count; i++)
{
list[i] = list[i].ToUpper();
}