我遇到了一种方法来改变foreach
循环中的列表,方法是转换为自己的列表,如下所示:
foreach (var item in myList.ToList())
{
//add or remove items from myList
}
(如果您尝试直接修改myList
,则抛出错误,因为枚举器基本上将其锁定)
这是有效的,因为它不是被修改的原始myList
。我的问题是,当循环结束时(即从garbage
方法返回的List
,此方法是否会创建ToList
?对于小循环,是否最好使用{ {1}}以避免产生垃圾?
答案 0 :(得分:5)
第二个列表将是垃圾,在构建第二个列表中使用的枚举器将有垃圾,并在枚举器中添加foreach
将产生的,无论是否有第二个列表,你都可以拥有它。
您应该切换到for
吗?也许, if 你可以指出这个代码区域是一个真正的性能瓶颈。否则,代码是为了简化和可维护性。
答案 1 :(得分:3)
是。 ToList()
会创建另一个需要进行垃圾回收的列表。
答案 2 :(得分:1)
这是一项有趣的技术,我将在未来牢记这一点! (我不敢相信我从未想过那个!)
无论如何,是的,你正在构建的列表并没有神奇地取消分配。这种技术可能存在的性能问题是:
List
,与IEnumerable
分开)。可能没什么大不了的,除非你频繁地这样做,或者IEnumerable
非常大。IEnumerable
来构建List
。IEnumerable
有副作用,则会全部由此过程触发。除非这实际上在内部循环中,或者您正在使用非常大的数据集,否则您可以毫无问题地执行此操作。
答案 3 :(得分:1)
是的,ToList()
方法会创建“垃圾”。我只是索引。
for (int i = MyList.Count - 1; 0 <= i; --i)
{
var item = MyList[i];
//add or remove items from myList
}
答案 4 :(得分:0)
它是非确定性的。但是,从调用ToList()
创建的引用最终将是GCd。
我不会太担心它,因为它最多只能包含引用或小值类型。